This file is indexed.

/usr/share/guile/site/scheme/kwargs.scm is in guile-library 0.2.2-0.2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
;; (scheme kwargs) -- an alternate implementation of keyword arguments
;; Copyright (C) 2003,2004,2007  Andy Wingo <wingo at pobox dot com>

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;; 
;; @c
;; Support for defining functions that take python-like keyword
;; arguments.
;; 
;; In one of his early talks, Paul Graham wrote about a large system
;; called "Rtml":
;;
;; @quotation
;;
;; Most of the operators in Rtml were designed to take keyword
;; parameters, and what a help that turned out to be. If I wanted to add
;; another dimension to the behavior of one of the operators, I could
;; just add a new keyword parameter, and everyone's existing templates
;; would continue to work. A few of the Rtml operators didn't take
;; keyword parameters, because I didn't think I'd ever need to change
;; them, and almost every one I ended up kicking myself about later. If
;; I could go back and start over from scratch, one of the things I'd
;; change would be that I'd make every Rtml operator take keyword
;; parameters.
;;
;; @end quotation
;;
;; @xref{scheme kwargs lambda/kwargs,,lambda/kwargs}, for documentation
;; and examples.
;;
;; @xref{Optional Arguments,,,guile,Guile Reference Manual}, for more
;; information on Guile's standard support for optional and keyword
;; arguments.
;; 
;; Quote taken from
;; @uref{http://lib.store.yahoo.net/lib/paulgraham/bbnexcerpts.txt}.
;;
;;; Code:

(define-module (scheme kwargs)
  :use-module (ice-9 optargs)
  :use-module (scheme documentation)
  :export (lambda/kwargs define/kwargs))

(define (until pred? list)
  "Returns the first elements of @var{list} for which @var{pred?} is false."
  (if (or (eq? list '()) (pred? (car list)))
      '()
      (cons (car list) (until pred? (cdr list)))))

(define-macro-with-docs (lambda/kwargs BINDINGS . BODY)
  "Defines a function that takes keyword arguments.

@var{bindings} is a list of bindings, each of which may either be a
symbol or a two-element symbol-and-default-value list. Symbols without
specified default values will default to @code{#f}.

For example:
@example
 (define frobulate (lambda/kwargs (foo (bar 13) (baz 42))
                     (list foo bar baz)))
 (frobulate) @result{} (#f 13 42)
 (frobulate #:baz 3) @result{} (#f 13 3)
 (frobulate #:foo 3) @result{} (3 13 42)
 (frobulate 3 4) @result{} (3 4 42)
 (frobulate 1 2 3) @result{} (1 2 3)
 (frobulate #:baz 2 #:bar 1) @result{} (#f 1 2)
 (frobulate 10 20 #:foo 3) @result{} (3 20 42)
@end example

This function differs from the standard @code{lambda*} provided by Guile
in that invoking the function will accept positional arguments.
As an example, the @code{lambda/kwargs} behaves more intuitively in the
following case:

@example
 ((lambda* (#:optional (bar 42) #:key (baz 73))
    (list bar baz))
  1 2) @result{} (1 73)
 ((lambda/kwargs ((bar 42) (baz 73))
    (list bar baz))
  1 2) @result{} (1 2)
@end example

The fact that @code{lambda*} accepts the extra @samp{2} argument is
probably just a bug. In any case, @code{lambda/kwargs} does the right
thing.
"
  (or (list? BINDINGS)
      (error "lambda/kwargs bindings must be a list"))
  (let ((lambda-gensym (gensym))
        (args-gensym (gensym))
        (positional (gensym))
        (keyword (gensym))
        (nbindings (length BINDINGS))
        (CANONICAL-BINDINGS (map (lambda (x)
                                   (if (list? x) x (list x #f)))
                                 BINDINGS))
        (VARIABLES (map (lambda (x) (if (list? x) (car x) x))
                        BINDINGS)))
    `(let ((,lambda-gensym
            (lambda ,args-gensym
              ,@(if (string? (car BODY)) (list (car BODY)) '())
              (let* ((,positional ((@@ (scheme kwargs) until)
                                   keyword? ,args-gensym))
                     (,keyword (list-tail ,args-gensym (length ,positional))))
                (if (> (length ,positional) ,nbindings)
                    (error "Too many positional arguments."))
                ((@ (ice-9 optargs) let-optional) ,positional
                  ,CANONICAL-BINDINGS
                  ;; ,@(map car CANONICAL-BINDINGS)
                  ((@ (ice-9 optargs) let-keywords) ,keyword
                    #f
                    ,(map list VARIABLES VARIABLES)
                    ,@(if (string? (car BODY)) (cdr BODY) BODY)))))))
       (set-procedure-property! ,lambda-gensym
                                'arglist
                                '(() () ,CANONICAL-BINDINGS #f #f))
       ,lambda-gensym)))
       
(define-macro-with-docs (define/kwargs what . body)
  "Defines a function that takes kwargs. @xref{scheme kwargs
lambda/kwargs}, for more information.
"
  `(define ,(car what) ((@ (scheme kwargs) lambda/kwargs) ,(cdr what) ,@body)))