Skip to content

Commit

Permalink
Refine bind-args yet further, so it can be used in macros.
Browse files Browse the repository at this point in the history
  • Loading branch information
cpressey committed Apr 20, 2012
1 parent 62703a4 commit 327f6bc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
4 changes: 0 additions & 4 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,6 @@ Plans
final-result and unknown-tag reply messages, particularly during `call`
and `respond`.

* A macro for asserting that the correct number of arguments have been
given to a macro. (Right now the `small` macros don't complain if
given too many arguments.)

* Some kind of macro for capturing the recursive function call pattern
(like `letrec`, but not necessary to support mutual recursion.) Possibly
called `bind-recur`. Also `let-recur` could build on that. Turn:
Expand Down
53 changes: 48 additions & 5 deletions doc/module/Bind-Args.markdown
Original file line number Diff line number Diff line change
@@ -1,36 +1,79 @@
Robin - Bind-Args module (provisional)
======================================

-> Tests for functionality "Interpret Robin Program"

`bind-args` is a macro for binding the arguments of another value to
identifiers, as well as asserting that the correct number of arguments
have been given to the macro.

This macro should really be defined in `small`, and used by the other
macros defined in `small` (right now they don't complain if given too
many arguments, and complain about an `expected-list` if given too few.)

### `bind-args` ###

`bind-args` takes a literal list of identifiers, and expresion which
evaluates to a literal list of expressions whose values are to be bound
to those identifiers, an expresion which evaluates to the environment in
which those expressions will be evaluated, and an expression to evaluate
in the new environment in which the identifiers are bound.

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind-args (a b) (1 2)
| (bind-args (a b) (literal (1 2)) (env)
| (list a b)))
= (1 2)

Expressions in the list of values are evaluated.

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind-args (a b) ((subtract 5 4) (subtract 10 1))
| (bind-args (a b) (literal ((subtract 5 4) (subtract 10 1))) (env)
| (list a b)))
= (1 9)

Too many or too few arguments will raise an `illegal-arguments`
exception.

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind-args (a b) (1)
| (bind-args (a b) (literal (1)) (env)
| (list a b)))
? uncaught exception: (illegal-arguments (1))

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind-args (a b) (1 2 3)
| (bind-args (a b) (literal (1 2 3)) (env)
| (list a b)))
? uncaught exception: (illegal-arguments (1 2 3))

The literal arguments are reported in the exception.

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind-args (a) ((subtract 5 4) (subtract 1 0))
| (bind-args (a) (literal ((subtract 5 4) (subtract 1 0))) (env)
| a))
? uncaught exception: (illegal-arguments ((subtract 5 4) (subtract 1 0)))

This is how it might be used in a macro definition. The reason for the
seemingly strange requirements of the second and third arguments should
become clear here: typically you would just pass the macro's `args` and
`env` to those arguments.

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind add (macro (self args env)
| (bind-args (a b) args env
| (subtract a (subtract 0 b))))
| (add 4 (add 5 6))))
= 15

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind add (macro (self args env)
| (bind-args (a b) args env
| (subtract a (subtract 0 b))))
| (bind r 7
| (add r r))))
= 14

| (robin (0 1) ((small (0 1) *) (bind-args (0 1) *))
| (bind add (macro (self args env)
| (bind-args (a b) args env
| (subtract a (subtract 0 b))))
| (add (subtract 0 0))))
? uncaught exception: (illegal-arguments ((subtract 0 0)))
7 changes: 4 additions & 3 deletions module/bind-args_0_1.robin
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
(macro (self args env)
(let (
(id-list (head args))
(orig-val-list (head (tail args)))
(expr (head (tail (tail args))))
(orig-val-list (eval env (head (tail args))))
(given-env (eval env (head (tail (tail args)))))
(expr (head (tail (tail (tail args)))))
(bind-args-r (fun (self id-list val-list env-acc)
;''This will need to be converted into a macro at some point,
but for now, this is easier.''
Expand All @@ -19,7 +20,7 @@
(raise (list (literal illegal-arguments) orig-val-list))
(self self (tail id-list) (tail val-list)
(prepend
(list (head id-list) (eval env (head val-list)))
(list (head id-list) (eval given-env (head val-list)))
env-acc))))))
(new-env (bind-args-r bind-args-r id-list orig-val-list env))
)
Expand Down

0 comments on commit 327f6bc

Please sign in to comment.