|
- <!doctype html>
- <html lang="en">
- <head>
- <title></title>
- <!-- 2018-10-14 So 16:55 -->
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="generator" content="Org-mode">
- <meta name="author" content="Felix Brendel">
-
- <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
- <style type="text/css">
- /* org mode styles on top of twbs */
-
- html {
- position: relative;
- min-height: 100%;
- }
-
- body {
- font-size: 18px;
- margin-bottom: 105px;
- }
-
- footer {
- position: absolute;
- bottom: 0;
- width: 100%;
- height: 101px;
- background-color: #f5f5f5;
- }
-
- footer > div {
- padding: 10px;
- }
-
- footer p {
- margin: 0 0 5px;
- text-align: center;
- font-size: 16px;
- }
-
- #table-of-contents {
- margin-top: 20px;
- margin-bottom: 20px;
- }
-
- blockquote p {
- font-size: 18px;
- }
-
- pre {
- font-size: 16px;
- }
-
- .footpara {
- display: inline-block;
- }
-
- figcaption {
- font-size: 16px;
- color: #666;
- font-style: italic;
- padding-bottom: 15px;
- }
-
- /* from twbs docs */
-
- .bs-docs-sidebar.affix {
- position: static;
- }
- @media (min-width: 768px) {
- .bs-docs-sidebar {
- padding-left: 20px;
- }
- }
-
- /* All levels of nav */
- .bs-docs-sidebar .nav > li > a {
- display: block;
- padding: 4px 20px;
- font-size: 14px;
- font-weight: 500;
- color: #999;
- }
- .bs-docs-sidebar .nav > li > a:hover,
- .bs-docs-sidebar .nav > li > a:focus {
- padding-left: 19px;
- color: #A1283B;
- text-decoration: none;
- background-color: transparent;
- border-left: 1px solid #A1283B;
- }
- .bs-docs-sidebar .nav > .active > a,
- .bs-docs-sidebar .nav > .active:hover > a,
- .bs-docs-sidebar .nav > .active:focus > a {
- padding-left: 18px;
- font-weight: bold;
- color: #A1283B;
- background-color: transparent;
- border-left: 2px solid #A1283B;
- }
-
- /* Nav: second level (shown on .active) */
- .bs-docs-sidebar .nav .nav {
- display: none; /* Hide by default, but at >768px, show it */
- padding-bottom: 10px;
- }
- .bs-docs-sidebar .nav .nav > li > a {
- padding-top: 1px;
- padding-bottom: 1px;
- padding-left: 30px;
- font-size: 12px;
- font-weight: normal;
- }
- .bs-docs-sidebar .nav .nav > li > a:hover,
- .bs-docs-sidebar .nav .nav > li > a:focus {
- padding-left: 29px;
- }
- .bs-docs-sidebar .nav .nav > .active > a,
- .bs-docs-sidebar .nav .nav > .active:hover > a,
- .bs-docs-sidebar .nav .nav > .active:focus > a {
- padding-left: 28px;
- font-weight: 500;
- }
-
- /* Nav: third level (shown on .active) */
- .bs-docs-sidebar .nav .nav .nav {
- padding-bottom: 10px;
- }
- .bs-docs-sidebar .nav .nav .nav > li > a {
- padding-top: 1px;
- padding-bottom: 1px;
- padding-left: 40px;
- font-size: 12px;
- font-weight: normal;
- }
- .bs-docs-sidebar .nav .nav .nav > li > a:hover,
- .bs-docs-sidebar .nav .nav .nav > li > a:focus {
- padding-left: 39px;
- }
- .bs-docs-sidebar .nav .nav .nav > .active > a,
- .bs-docs-sidebar .nav .nav .nav > .active:hover > a,
- .bs-docs-sidebar .nav .nav .nav > .active:focus > a {
- padding-left: 38px;
- font-weight: 500;
- }
-
- /* Show and affix the side nav when space allows it */
- @media (min-width: 992px) {
- .bs-docs-sidebar .nav > .active > ul {
- display: block;
- }
- /* Widen the fixed sidebar */
- .bs-docs-sidebar.affix,
- .bs-docs-sidebar.affix-bottom {
- width: 213px;
- }
- .bs-docs-sidebar.affix {
- position: fixed; /* Undo the static from mobile first approach */
- top: 20px;
- }
- .bs-docs-sidebar.affix-bottom {
- position: absolute; /* Undo the static from mobile first approach */
- }
- .bs-docs-sidebar.affix .bs-docs-sidenav,.bs-docs-sidebar.affix-bottom .bs-docs-sidenav {
- margin-top: 0;
- margin-bottom: 0
- }
- }
- @media (min-width: 1200px) {
- /* Widen the fixed sidebar again */
- .bs-docs-sidebar.affix-bottom,
- .bs-docs-sidebar.affix {
- width: 263px;
- }
- }
- </style>
- <script type="text/javascript">
- $(function() {
- 'use strict';
-
- $('.bs-docs-sidebar li').first().addClass('active');
-
- $(document.body).scrollspy({target: '.bs-docs-sidebar'});
-
- $('.bs-docs-sidebar').affix();
- });
- </script>
- </head>
- <body>
- <div id="content" class="container">
- <div class="row"><div class="col-md-9"><h1 class="title"></h1>
- <div id="outline-container-sec-1" class="outline-2">
- <h2 id="sec-1"><span class="section-number-2">1</span> Arguments</h2>
- <div class="outline-text-2" id="text-1">
- <p>
- In Emacs lisp, keyword arguments must be passed in the same order as they were
- defined in, so <code>((lambda (a &key b c) (+ a b c)) 1 3 :b 2)</code> will preduce an
- error, because <code>b</code> was passed as last argument but was defined as second argument.
- </p>
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">3</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 <span style="color: #6c71c4;">:b</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">3</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:b</span> 2 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error</span>
- </pre>
- </div>
-
-
- <p>
- But if mulitiple keyword arguments are defined, their ordering does not matter.
- </p>
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b <span style="color: #268bd2;">&key</span> c <span style="color: #268bd2;">&key</span> d<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 <span style="color: #6c71c4;">:d</span> 4 <span style="color: #6c71c4;">:c</span> 3 <span style="color: #6c71c4;">:b</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">10</span>
- </pre>
- </div>
-
- <p>
- It is even possible to have a non keyword argument bewtween keyword arguments
- and when calling, switch the order.
- </p>
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b c <span style="color: #268bd2;">&key</span> d<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 <span style="color: #6c71c4;">:d</span> 4 3 <span style="color: #6c71c4;">:b</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">10</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b c <span style="color: #268bd2;">&key</span> d<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 <span style="color: #6c71c4;">:d</span> 4 <span style="color: #6c71c4;">:b</span> 2 3<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error</span>
- </pre>
- </div>
-
- <p>
- However somehow it is not possible to flip the ordering at the first argument
- </p>
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 2 <span style="color: #6c71c4;">:b</span> 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">3</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a <span style="color: #268bd2;">&key</span> b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:b</span> 2 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #268bd2;">&key</span> a b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:a</span> 2 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">3</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #268bd2;">&key</span> a b<span style="color: #b58900;">)</span> <span style="color: #b58900;">(</span>+ a b<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 <span style="color: #6c71c4;">:a</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error</span>
- </pre>
- </div>
-
- <p>
- So it seems, positional arguments have to be at the exact position they were
- defined in, but keyword arguments can appear in any order, but at the places
- where keyword arguments have been defined.
- </p>
- </div>
-
- <div id="outline-container-sec-1-1" class="outline-3">
- <h3 id="sec-1-1"><span class="section-number-3">1.1</span> Idea</h3>
- <div class="outline-text-3" id="text-1-1">
- <p>
- Every argument can be set using keys, but keyword arguments always come strictly
- after positional arguments
- </p>
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 3 4<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">ok</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 <span style="color: #6c71c4;">:c</span> 2 <span style="color: #6c71c4;">:d</span> 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">ok</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 <span style="color: #6c71c4;">:d</span> 1 <span style="color: #6c71c4;">:c</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">ok</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:d</span> 1 1 2 <span style="color: #6c71c4;">:c</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, keyword arguments must come last</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 <span style="color: #6c71c4;">:c</span> 2 <span style="color: #6c71c4;">:d</span> 1 <span style="color: #6c71c4;">:a</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, 'a' was passed two times</span>
-
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 <span style="color: #6c71c4;">:d</span> 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, c was not passed, but does not have a default value</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b c <span style="color: #6c71c4;">:default</span> 10 d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> 1 2 <span style="color: #6c71c4;">:d</span> 1<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">okay again</span>
- </pre>
- </div>
-
- <p>
- The drawback then is that you can never pass a keyword as a positional argument,
- because it will always try to assign the next argument to the variable defined
- by the keyword. You could still pass it as a keyword argument though. This is
- especially annoying because we want to use keywords as type identifiers.
- </p>
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span>= <span style="color: #2aa198;">(</span>type <span style="color: #2aa198;">"hello"</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:string</span><span style="color: #839496;">)</span>
- </pre>
- </div>
-
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"><span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>i-wanna-get-a-kw<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:hey</span><span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, unmatched value for keyword argument</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>i-wanna-get-a-kw<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:i-wanna-get-a-kw</span> <span style="color: #6c71c4;">:hey</span><span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">this would work again</span>
- </pre>
- </div>
-
- <p>
- Other Idea is to mark the place in the parameter list where keyword argumetns
- start and arguments before that are positional and will not be stuffed into
- key-value pairs and arguments after that will be keyword arguments
- </p>
-
- <div class="org-src-container">
-
- <pre class="src src-ebnf"><lambda list> -> <positional argument>*
- [:keys ( <keyword arguments> [:defaults-to <value>])*]
- [(:rest <rest argument>)|(:body <body argument>)]
- </pre>
- </div>
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp"> <span style="color: #839496;">(</span>= <span style="color: #2aa198;">(</span>type <span style="color: #2aa198;">"hello"</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:string</span><span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">this will work again because (=) does</span>
- <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">not use keyword arguments</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>i-wanna-get-a-kw<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span> <span style="color: #6c71c4;">:hey</span><span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">would work because of the same reason</span>
-
- <span style="color: #839496;">(</span>define fun
- <span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #6c71c4;">:keys</span> a b c d<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>+ a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #839496;">)</span>
-
- <span style="color: #839496;">(</span>fun 1 2 3 4<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">okay</span>
- <span style="color: #839496;">(</span>fun 1 2 <span style="color: #6c71c4;">:d</span> 3 <span style="color: #6c71c4;">:c</span> 4<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">okay</span>
- <span style="color: #839496;">(</span>fun 1 2 <span style="color: #6c71c4;">:d</span> 3 <span style="color: #6c71c4;">:c</span> 4 <span style="color: #6c71c4;">:a</span> 2<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, 'a' was passed two times</span>
- <span style="color: #839496;">(</span>fun <span style="color: #6c71c4;">:c</span> 1 <span style="color: #6c71c4;">:b</span> 2 <span style="color: #6c71c4;">:d</span> 3 <span style="color: #6c71c4;">:a</span> 4<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">okay</span>
- <span style="color: #839496;">(</span>fun <span style="color: #6c71c4;">:c</span> 1 <span style="color: #6c71c4;">:b</span> 2 <span style="color: #6c71c4;">:d</span> 3 4<span style="color: #839496;">)</span> <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">error, positional argument after keyword</span>
- <span style="color: #49974A; font-style: italic;">;; </span><span style="color: #49974A; font-style: italic;">and fun does not accept rest parameter</span>
-
- <span style="color: #839496;">(</span>define fun2
- <span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #6c71c4;">:quoted</span> op a b <span style="color: #6c71c4;">:keys</span> c d <span style="color: #6c71c4;">:rest</span> r<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>print r<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>op a b c d<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #839496;">)</span>
-
- >> <span style="color: #839496;">(</span>fun2 * 1 2 <span style="color: #6c71c4;">:c</span> 3 <span style="color: #6c71c4;">:d</span> 4 <span style="color: #2aa198;">"this"</span> <span style="color: #2aa198;">"can"</span> <span style="color: #6c71c4;">:be</span> <span style="color: #2aa198;">"whatever"</span><span style="color: #839496;">)</span>
- <span style="color: #839496;">(</span><span style="color: #2aa198;">"this"</span> <span style="color: #2aa198;">"can"</span> <span style="color: #6c71c4;">:be</span> <span style="color: #2aa198;">"whatever"</span><span style="color: #839496;">)</span>
- 24
-
-
- >> <span style="color: #839496;">(</span>define print-before-eval <span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #6c71c4;">:body</span> expr<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>print expr<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>eval expr<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #839496;">)</span>
- >> <span style="color: #839496;">(</span>define r <span style="color: #2aa198;">(</span>print-before-eval <span style="color: #b58900;">(</span>+ 1 2 3<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #839496;">)</span>
- <span style="color: #839496;">(</span>+ 1 2 3<span style="color: #839496;">)</span>
- >> r
- 6
-
- </pre>
- </div>
-
- <p>
- Wait this does not work either because you won't be able to pass keywords into
- rest.
- </p>
-
- <p>
- <b>Unrealated Idea: Distinguish between functions and macros</b>
- </p>
-
- <p>
- The difference is really simple:
- </p>
- <dl class="org-dl">
- <dt> Function </dt><dd>like a lambda, but no argument is automatically quoted
- </dd>
- <dt> Macro </dt><dd>like a lambda, but every argument is automatically quoted
- </dd>
- </dl>
-
- <p>
- This is important, because a macro should not introduce a new environment, but
- use the one it lives in.
- </p>
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp">>> <span style="color: #839496;">(</span>define print-before-eval <span style="color: #2aa198;">(</span>macro <span style="color: #b58900;">(</span><span style="color: #6c71c4;">:rest</span> expr<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>print expr<span style="color: #b58900;">)</span>
- <span style="color: #b58900;">(</span>eval expr<span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
-
- </pre>
- </div>
- </div>
- </div>
-
- <div id="outline-container-sec-1-2" class="outline-3">
- <h3 id="sec-1-2"><span class="section-number-3">1.2</span> the actual problem</h3>
- <div class="outline-text-3" id="text-1-2">
- <p>
- We have some requirements to the arguments:
- </p>
- <ul class="org-ul">
- <li>positional arguments (always required, no default value)
- </li>
- <li>keyword arguments (always come after positionals), can be not passed if there
- is a default value
- </li>
- <li>We want to be able to have a rest paramter, where everything is dumped in to
- that exceeds the other parameters
- </li>
- </ul>
-
- <p>
- <b>The problem is, we have no way of knowing if the current keyword we are
- reading is still part of the keyword block or part of the rest paramter.</b>
- </p>
-
- <p>
- Consider:
- </p>
-
- <div class="org-src-container">
-
- <pre class="src src-emacs-lisp">>> <span style="color: #839496;">(</span>define fun <span style="color: #2aa198;">(</span><span style="color: #859900;">lambda</span> <span style="color: #b58900;">(</span>a b <span style="color: #6c71c4;">:key</span> c d <span style="color: #6c71c4;">:defaults-to</span> 4 <span style="color: #6c71c4;">:rest</span><span style="color: #b58900;">)</span> nil<span style="color: #2aa198;">)</span><span style="color: #839496;">)</span>
- >> <span style="color: #839496;">(</span>fun 1 2 <span style="color: #6c71c4;">:c</span> 3 <span style="color: #6c71c4;">:d</span> 5<span style="color: #839496;">)</span>
- </pre>
- </div>
- <p>
- What should this be evaluated to?
- </p>
-
- <table class="table table-striped table-bordered table-hover table-condensed">
-
-
- <colgroup>
- <col class="left">
-
- <col class="right">
-
- <col class="right">
-
- <col class="right">
-
- <col class="right">
-
- <col class="left">
- </colgroup>
- <thead>
- <tr>
- <th scope="col" class="text-left"> </th>
- <th scope="col" class="text-right">a</th>
- <th scope="col" class="text-right">b</th>
- <th scope="col" class="text-right">c</th>
- <th scope="col" class="text-right">d</th>
- <th scope="col" class="text-left">rest</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="text-left">v1</td>
- <td class="text-right">1</td>
- <td class="text-right">2</td>
- <td class="text-right">3</td>
- <td class="text-right">5</td>
- <td class="text-left">nil</td>
- </tr>
-
- <tr>
- <td class="text-left">v2</td>
- <td class="text-right">1</td>
- <td class="text-right">2</td>
- <td class="text-right">3</td>
- <td class="text-right">4</td>
- <td class="text-left">(:d 5)</td>
- </tr>
- </tbody>
- </table>
-
- <p>
- It is ambiguous. It is however important to note that this can only happen when
- there are optinal keyword arguments (keyword arguments with default values).
- Otherwise we could always know which variables are set and wich have not been
- set to see if we are in an errornious state.
- </p>
- </div>
- </div>
-
- <div id="outline-container-sec-1-3" class="outline-3">
- <h3 id="sec-1-3"><span class="section-number-3">1.3</span> Solution</h3>
- <div class="outline-text-3" id="text-1-3">
- <p>
- We can resolve that problem by always making the the decision of chosing <code>v1</code>
- between <code>v1</code> and <code>v1</code>. This means, when we are expecting to read kwargs, and we
- encounter an kwarg, try to apply it (this can fail, for two reasons:
- </p>
-
- <ol class="org-ol">
- <li>The keyword has no following value
- </li>
- <li>The keyword is not a keyword argument in the funciton
- </li>
- </ol>
-
- <p>
- ), if it fails treat it as part of the rest arguments, and read all the
- following arguments into the rest arguments, or if it works, use it as the
- keyword argument.
- </p>
- </div>
- </div>
-
- <div id="outline-container-sec-1-4" class="outline-3">
- <h3 id="sec-1-4"><span class="section-number-3">1.4</span> Implementation</h3>
- <div class="outline-text-3" id="text-1-4">
- <div class="org-src-container">
-
- <pre class="src src-c"><span style="color: #859900;">typedef</span> <span style="color: #859900;">struct</span> <span style="color: #839496;">{</span>
- <span style="color: #268bd2;">char</span>* <span style="color: #6c71c4;">docstring</span>;
- <span style="color: #268bd2;">char</span>** <span style="color: #6c71c4;">positional_arguments</span>;
- <span style="color: #859900;">struct</span> <span style="color: #2aa198;">{</span>
- <span style="color: #268bd2;">char</span>* <span style="color: #6c71c4;">identifier</span>;
- <span style="color: #268bd2;">Ast_node</span>* <span style="color: #6c71c4;">default_value</span>; <span style="color: #49974A; font-style: italic;">// </span><span style="color: #49974A; font-style: italic;">will be nullptr if no defalut value was declared</span>
- <span style="color: #2aa198;">}</span>* <span style="color: #6c71c4;">keyword_arguments</span>;
- <span style="color: #268bd2;">char</span>* <span style="color: #6c71c4;">rest_argument</span>; <span style="color: #49974A; font-style: italic;">// </span><span style="color: #49974A; font-style: italic;">will be nullptr if no rest argument is declared</span>
- <span style="color: #268bd2;">Ast_Node_array_list</span> <span style="color: #6c71c4;">body</span>;
- <span style="color: #839496;">}</span> <span style="color: #268bd2;">lambda</span>;
- </pre>
- </div>
- </div>
- </div>
- </div>
- </div><div class="col-md-3"><nav id="table-of-contents">
- <div id="text-table-of-contents" class="bs-docs-sidebar">
- <ul class="nav">
- <li><a href="#sec-1">1. Arguments</a>
- <ul class="nav">
- <li><a href="#sec-1-1">1.1. Idea</a></li>
- <li><a href="#sec-1-2">1.2. the actual problem</a></li>
- <li><a href="#sec-1-3">1.3. Solution</a></li>
- <li><a href="#sec-1-4">1.4. Implementation</a></li>
- </ul>
- </li>
- </ul>
- </div>
- </nav>
- </div></div></div>
- <footer id="postamble" class="">
- <div><p class="author">Author: Felix Brendel</p>
- <p class="date">Created: 2018-10-14 So 16:55</p>
- <p class="creator"><a href="http://www.gnu.org/software/emacs/">Emacs</a> 26.0.91 (<a href="http://orgmode.org">Org-mode</a> 9.1.13)</p>
- </div>
- </footer>
- </body>
- </html>
|