Page:Ludovic Courtès - Functional Package Management with Guix.djvu/5

From Wikisource
Jump to navigation Jump to search
This page has been proofread, but needs to be validated.
 1: (define hello 
 2:   (package 
 3:     (name "hello") 
 4:     (version "2.8") 
 5:     (source (origin 
 6:               (method url-fetch) 
 7:               (uri (string-append "mirror://gnu/hello/hello-" 
 8:                                   version ".tar.gz")) 
 9:               (sha256 (base32 "0wqd8...")))) 
10:     (build-system gnu-build-system) 
11:     (arguments 
12:       (#:configure-flags 
13:         ("-disable-color" 
14:           ,(string-append "-with-gawk=" 
15:                           (assoc-ref %build-inputs "gawk"))))) 
16:     (inputs (("gawk" ,gawk))) 
17:     (synopsis "GNU Hello") 
18:     (description "An illustration of GNU’s engineering practices.") 
19:     (home-page "http://www.gnu.org/software/hello/") 
20:     (license gpl3+)))
Figure 4
A package definition using the high-level interface.


field names to field indexes, such that that mapping incurs no run-time overhead, in a way similar to SRFI-35 records.[1] They also bind fields as per letrec*, allowing them to refer to one another, as on line 8 of Figure 4. The base32 macro simply converts a literal string containing a base-32 representation into a bytevector literal, again allowing the conversion and error-checking to be done at expansion time rather than at run-time.

 1: (define-record-type* <package>
 2:   package make-package 
 3:   package? 
 4: 
 5: (name package-name) 
 6: (version package-version) 
 7: (source package-source) 
 8: (build-system package-build-system) 
 9: (arguments package-arguments 
10:            (default ()) (thunked)) 
11:  
12:  (inputs package-inputs 
13:          (default ()) (thunked)) 
14:  (propagated-inputs package-propagated-inputs 
15:                     (default ())) 
16:  
17:  (synopsis package-synopsis) 
18:  (description package-description) 
19:  (license package-license) 
20:  (home-page package-home-page) 
21:  
22:  (location package-location 
23:     (default (current-source -location))))
Figure 5
Definition of the package record type.


The package and origin macros are generated by a syntax-case hygienic macro[2], define-record-type*, which is layered above SRFI-9’s syntactic record layer.[3] Figure 5 shows the definition of the <package> record type (the <origin> record type, not shown here, is defined similarly.) In addition to the name of a procedural constructor, make-package, as with SRFI-9, the name of a syntactic constructor, package, is given (likewise, origin is the syntactic constructor of <origin>.) Fields may have a default value, introduced with the default keyword. An interesting use of default values is the location field: its default value is the result of current-source-location, which is itself a built-in macro that expands to the source file location of the package form. Thus, records defined with the package macro automatically have a location field denoting their source file location. This allows the user interface to report source file location in error messages and in package search results, thereby making it easier for users to "jump into" the distribution’s source, which is one of our goals.

1: (package (inherit hello)
2:   (version "2.7")
3:   (source 
4:     (origin 
5:       (method url-fetch) 
6:       (uri 
7:        "mirror://gnu/hello/hello-2.7 .tar.gz") 
8:       (sha256 
9:        (base32 "7dqw3...")))))
Figure 6
Creating a variant of the hello package.


The syntactic constructors generated by define-record-type* additionally support a form of functional setters (sometimes referred to as "lenses"[4]), via the inherit keyword. It allows programmers to create new instances that differ from an existing instance by one or more field values. A typical use case is shown in Figure 6: the expression shown evaluates to a new <package> instance whose fields all have

  1. R. Kelsey, M. Sperber. Conditions. 2002. http://srfi.schemers.org/srfi-35/srfi-35.html.
  2. M. Sperber, R. K. Dybvig, M. Flatt, A. V. Straaten, R. B. Findler, J. Matthews. Revised6 Report on the Algorithmic Language Scheme. In Journal of Functional Programming, 19, 7 2009, pp. 1-301.
  3. R. Kelsey. Defining Record Types. 1999. http://srfi.schemers.org/srfi-9/srfi-9.html.
  4. T. Morris. Asymmetric Lenses in Scala. 2012. http://days2012.scala-lang.org/.

    which are essentially vectors of a disjoint type. In Guile they are lightweight compared to CLOS-style objects, both in terms of run time and memory footprint. Furthermore, make-struct is subject to inlining.