diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2014-08-15 16:22:11 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2014-08-15 16:26:28 +0200 |
| commit | b9b8607824448cd6bd152ca0ede460a7f44f3b2b (patch) | |
| tree | 712ba5198db83298d6dbf5a65d54189ccfbcae87 | |
| parent | c0b9213dbbf2d54c58e8fb62a52efc98f184d859 (diff) | |
Add (guix monad-repl).
* guix/monad-repl.scm: New file.
* guix.scm: Add it.
* Makefile.am (MODULES): Add it.
* doc/guix.texi (The Store Monad): Document it.
| -rw-r--r-- | Makefile.am | 1 | ||||
| -rw-r--r-- | doc/guix.texi | 27 | ||||
| -rw-r--r-- | guix.scm | 1 | ||||
| -rw-r--r-- | guix/monad-repl.scm | 81 |
4 files changed, 110 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index eab126acee6..17a676ac543 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -37,6 +37,7 @@ MODULES = \ | |||
| 37 | guix/download.scm \ | 37 | guix/download.scm \ |
| 38 | guix/git-download.scm \ | 38 | guix/git-download.scm \ |
| 39 | guix/monads.scm \ | 39 | guix/monads.scm \ |
| 40 | guix/monad-repl.scm \ | ||
| 40 | guix/gexp.scm \ | 41 | guix/gexp.scm \ |
| 41 | guix/profiles.scm \ | 42 | guix/profiles.scm \ |
| 42 | guix/serialization.scm \ | 43 | guix/serialization.scm \ |
diff --git a/doc/guix.texi b/doc/guix.texi index a4ffa8524b5..92eccad118e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi | |||
| @@ -1937,6 +1937,33 @@ effect, one must use @code{run-with-store}: | |||
| 1937 | @result{} /gnu/store/...-profile.sh | 1937 | @result{} /gnu/store/...-profile.sh |
| 1938 | @end example | 1938 | @end example |
| 1939 | 1939 | ||
| 1940 | Note that the @code{(guix monad-repl)} module extends Guile's REPL with | ||
| 1941 | new ``meta-commands'' to make it easier to deal with monadic procedures: | ||
| 1942 | @code{run-in-store}, and @code{enter-store-monad}. The former, is used | ||
| 1943 | to ``run'' a single monadic value through the store: | ||
| 1944 | |||
| 1945 | @example | ||
| 1946 | scheme@@(guile-user)> ,run-in-store (package->derivation hello) | ||
| 1947 | $1 = #<derivation /gnu/store/@dots{}-hello-2.9.drv => @dots{}> | ||
| 1948 | @end example | ||
| 1949 | |||
| 1950 | The latter enters a recursive REPL, where all the return values are | ||
| 1951 | automatically run through the store: | ||
| 1952 | |||
| 1953 | @example | ||
| 1954 | scheme@@(guile-user)> ,enter-store-monad | ||
| 1955 | store-monad@@(guile-user) [1]> (package->derivation hello) | ||
| 1956 | $2 = #<derivation /gnu/store/@dots{}-hello-2.9.drv => @dots{}> | ||
| 1957 | store-monad@@(guile-user) [1]> (text-file "foo" "Hello!") | ||
| 1958 | $3 = "/gnu/store/@dots{}-foo" | ||
| 1959 | store-monad@@(guile-user) [1]> ,q | ||
| 1960 | scheme@@(guile-user)> | ||
| 1961 | @end example | ||
| 1962 | |||
| 1963 | @noindent | ||
| 1964 | Note that non-monadic values cannot be returned in the | ||
| 1965 | @code{store-monad} REPL. | ||
| 1966 | |||
| 1940 | The main syntactic forms to deal with monads in general are described | 1967 | The main syntactic forms to deal with monads in general are described |
| 1941 | below. | 1968 | below. |
| 1942 | 1969 | ||
| @@ -30,6 +30,7 @@ | |||
| 30 | ftp-client | 30 | ftp-client |
| 31 | gexp | 31 | gexp |
| 32 | monads | 32 | monads |
| 33 | monad-repl | ||
| 33 | packages | 34 | packages |
| 34 | store | 35 | store |
| 35 | utils)) | 36 | utils)) |
diff --git a/guix/monad-repl.scm b/guix/monad-repl.scm new file mode 100644 index 00000000000..5242f5448b0 --- /dev/null +++ b/guix/monad-repl.scm | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; Copyright © 2014 Ludovic Courtès <ludo@gnu.org> | ||
| 3 | ;;; | ||
| 4 | ;;; This file is part of GNU Guix. | ||
| 5 | ;;; | ||
| 6 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | ||
| 7 | ;;; under the terms of the GNU General Public License as published by | ||
| 8 | ;;; the Free Software Foundation; either version 3 of the License, or (at | ||
| 9 | ;;; your option) any later version. | ||
| 10 | ;;; | ||
| 11 | ;;; GNU Guix is distributed in the hope that it will be useful, but | ||
| 12 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;;; GNU General Public License for more details. | ||
| 15 | ;;; | ||
| 16 | ;;; You should have received a copy of the GNU General Public License | ||
| 17 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | |||
| 19 | (define-module (guix monad-repl) | ||
| 20 | #:use-module (guix store) | ||
| 21 | #:use-module (guix monads) | ||
| 22 | #:use-module (ice-9 pretty-print) | ||
| 23 | #:use-module (system repl repl) | ||
| 24 | #:use-module (system repl common) | ||
| 25 | #:use-module (system repl command) | ||
| 26 | #:use-module (system base language) | ||
| 27 | #:use-module (system base compile) | ||
| 28 | #:use-module (srfi srfi-26) | ||
| 29 | #:export (run-in-store | ||
| 30 | enter-store-monad)) | ||
| 31 | |||
| 32 | ;;; Comment: | ||
| 33 | ;;; | ||
| 34 | ;;; This modules provides a couple of REPL meta-commands that make it easier | ||
| 35 | ;;; to work with monadic procedures in the store monad. | ||
| 36 | ;;; | ||
| 37 | ;;; Code: | ||
| 38 | |||
| 39 | (define* (monad-language monad run #:optional (name 'monad)) | ||
| 40 | "Return a language with a special evaluator that causes monadic values | ||
| 41 | to be \"run\" in MONAD using procedure RUN." | ||
| 42 | (let ((scheme (lookup-language 'scheme))) | ||
| 43 | (define (evaluate-monadic-expression exp env) | ||
| 44 | (let ((mvalue (compile exp #:to 'value #:env env))) | ||
| 45 | (run mvalue))) | ||
| 46 | |||
| 47 | (make-language #:name name | ||
| 48 | #:title "Monad" | ||
| 49 | #:reader (language-reader scheme) | ||
| 50 | #:compilers (language-compilers scheme) | ||
| 51 | #:decompilers (language-decompilers scheme) | ||
| 52 | #:evaluator evaluate-monadic-expression | ||
| 53 | #:printer (language-printer scheme) | ||
| 54 | #:make-default-environment | ||
| 55 | (language-make-default-environment scheme)))) | ||
| 56 | |||
| 57 | (define (store-monad-language) | ||
| 58 | "Return a compiler language for the store monad." | ||
| 59 | (let ((store (open-connection))) | ||
| 60 | (monad-language %store-monad | ||
| 61 | (cut run-with-store store <>) | ||
| 62 | 'store-monad))) | ||
| 63 | |||
| 64 | (define-meta-command ((run-in-store guix) repl (form)) | ||
| 65 | "run-in-store EXP | ||
| 66 | Run EXP through the store monad." | ||
| 67 | (let ((value (with-store store | ||
| 68 | (run-with-store store (repl-eval repl form))))) | ||
| 69 | (run-hook before-print-hook value) | ||
| 70 | (pretty-print value))) | ||
| 71 | |||
| 72 | (define-meta-command ((enter-store-monad guix) repl) | ||
| 73 | "enter-store-monad | ||
| 74 | Enter a REPL for values in the store monad." | ||
| 75 | (let ((new (make-repl (store-monad-language)))) | ||
| 76 | ;; Force interpretation so that our specially-crafted language evaluator | ||
| 77 | ;; is actually used. | ||
| 78 | (repl-option-set! new 'interp #t) | ||
| 79 | (run-repl new))) | ||
| 80 | |||
| 81 | ;;; monad-repl.scm ends here | ||
