[Larceny-users] Larceny basics

Felix felixluser at pnkfx.org
Fri Aug 31 16:12:06 EDT 2007


Dan-

On Aug 31, 2007, at 3:13 PM, Dan Muresan wrote:

> Hi all,
>
> I've recently discovered (and installed) Larceny, and I have a  
> couple of basic questions:
>
> 1) Where's the most complete documentation? I see that Larceny  
> supports a (require ...) form, but it doesn't seem to be documented  
> on the website.

There is an auto-built copy of the user documentation at the  
following url:
http://larceny.ccs.neu.edu/doc/

However, the user documentation won't actually help you understand  
the require procedure, since we neglected to put documentation for it  
in there.

One reason for this neglect is that at the time that we (re) 
implemented require, we expected the need for the require procedure  
to become obsolete with the shift to R6RS style libraries.  You can  
see some notes on this at the following page on the Larceny Wiki.

http://larceny.ccs.neu.edu/larceny-trac/wiki/RationalizingLarceny

I am not sure how much effort we will put into documenting the  
require procedure, since I am not certain that it will remain an  
established part of Larceny.

For the time being, the best ways I can suggest to understand the  
behavior of require (or any other feature you cannot find  
documentation for) is to ask about it on this list, or to read the  
source code for the feature.

In this case, the relevant source code for require is here:

http://larceny.ccs.neu.edu/larceny-trac/browser/trunk/larceny_src/src/ 
Lib/Common/require.sch

(I normally would not point a user at a source file and expect that  
to suffice, but this file is short, reasonably well documented, and  
factored into small chunks, so I hope you will forgive me for doing  
so in this particular case.)

A three sentence description of the require form:
(require 'lib) searches directories given by the current-require-path  
parameter for a Scheme file matching lib and loads the first such  
file it finds.  Relative paths in the directory list are resolved  
with respect to the current-larceny-root parameter.  Repeat attempts  
to load lib again have no effect.

Here is an example usage:

% larceny
Larceny v0.94 "Doomsday Device" (Aug 14 2007 10:56:17,  
precise:Linux:unified)
larceny.heap, built on Wed Aug  1 12:53:28 EDT 2007

 > (load-verbose #t) ;; instrument load to track require's behavior
#t

 > (apropos 'require) ;; will fail since apropos procedure is not yet  
defined


Error: Undefined global variable "apropos".
Entering debugger; type "?" for help.
debug> q

 > (require 'apropos) ;; will load apropos library

; Loading /home/pnkfelix/larcenydev/trunk/larceny_src/lib/Standard/ 
apropos.sch
; Loading /home/pnkfelix/larcenydev/trunk/larceny_src/lib/Base/ 
string.fasl
; Loading /home/pnkfelix/larcenydev/trunk/larceny_src/lib/Base/ 
list.fasl#t

 > (apropos 'require) ;; now apropos will work
(clear-require-loaded-files!
   current-require-path
   require)

 > (require 'apropos) ;; now no load will occur because apropos is  
already loaded
#f


> 2) Most of my Scheme programs (usually developed for SISC and/or  
> Chicken) use the popular SRFI's (1, 8, 9, 13, 43, 69 etc)  
> extensively; I usually load them with (require-extension (srfi n))  
> in the beginning of my programs. What's the easiest way to port to  
> Larceny? Should I copy the reference implementations?

I assume that when you refer to require-extension, you are referring  
to the special form defined in SRFI-55?

We do not have an implementation of SRFI-55 in the Larceny  
distribution.  I suspect that the reference implementation would be  
an okay stopgap measure, with two caveats:

1. You would still have to write down several invocations of register- 
extension somewhere (one for each srfi that you wanted to make  
available via SRFI-55).  Larceny's require function used to have an  
internal table mapping symbols to source files (which would be the  
analogous thing to the N invocations of register-extension that I am  
imagining), but now searches a set of paths looking for matching  
files.  So that's one reason that a Larceny-specific implementation  
of SRFI-55 that used require might be more appropriate.

2. The reference implementation does not seem to cache whether an  
extension has already been required; it will reload each extension  
every time require-extension is evaluated (I think).  That is a  
second reason that a Larceny-specific implementation of SRFI-55 atop  
the require procedure might be more appropriate.

A minimal port of require-extension atop Larceny's require might be a  
pretty simple syntax-rules macro.  Here's a stab at one:

(define-syntax require-extension
   (syntax-rules (srfi)
     ((_ (srfi m n ...))
      (for-each
       (lambda (i) (require (string-append "srfi-" (number->string i))))
       '(m n ...)))))

Depending on one's interpretation of SRFI-55, this may be a fine  
implementation of require-extension for Larceny.

-Felix

p.s. (Only if you're interested) there is one feature missing from  
the above SRFI-55 implementation that I, as a user, would desire:  
expansion of a require-extension form should extend the compile-time  
syntactic environment with any syntax that is provided by the SRFI's  
that the form is requiring.

I spent some time over a year ago trying to incorporate such a  
feature into Larceny's require form; if you're curious about the  
issues I encountered, you can go read:

http://larceny.ccs.neu.edu/larceny-trac/wiki/ExtendingRequire

In the end I stopped trying to make this work, in part because I  
expected that R6RS library support would obviate the need for such  
functionality, and in part because it really was fundamentally  
difficult to implement properly.




More information about the Larceny-users mailing list