For Gauche 0.9.9

Next: , Previous: , Up: Programming in Gauche   [Contents][Index]

3.2 Interactive development

When gosh is invoked without any script files, it goes into interactive read-eval-print loop (REPL).

To exit the interpreter, type EOF (usually Control-D in Unix terminals) or evaluate (exit).

In the interactive session, gosh loads and imports gauche.interactive module (see Interactive session) into user module, for the convenience. Also, if there’s a file .gaucherc under the user’s home directory. You may put settings there that would help interactive debugging. (As of Gauche release 0.7.3, .gaucherc is no longer loaded when gosh is run in script mode.)

Note that .gaucherc is always loaded in the user module, even if gosh is invoked with -r7 option. The file itself is a Gauche-specific feature, so you don’t need to consider portability in it.

I recommend you to run gosh inside Emacs, for it has rich features useful to interact with internal Scheme process. Put the following line to your .emacs file:

(setq scheme-program-name "gosh -i")

And you can run gosh by M-x run-scheme.

If you set an environment variable GAUCHE_READ_EDIT and the terminal is capable of cursor control, gosh starts with an experimental line-editor. After typing input, you can move back and change text, or invoke older input to edit, with Emacs-like key bindings. This feature is experimental—only very rudimental editor operations are supported, and you may experience weird behaviors. Let us know if you encounter buggy behaviors.

When gosh is invoked with read-edit mode, you see the prompt gosh$, instead of the default gosh>.

If you want to use multibyte characters in the interaction, make sure your terminal’s settings is in sync with gosh’s internal character encodings.

Previous: , Up: Interactive development   [Contents][Index]

3.2.1 Working in REPL

When you enter REPL, Gauche prompts you to enter a Scheme expression:


After you complete a Scheme expression and type ENTER, the result of evaluation is printed.

gosh> (+ 1 2)

The REPL session binds the last three results of evaluation in the global variables *1, *2 and *3. You can use the previous results via those history variables in subsequent expressions.

gosh> *1
gosh> (+ *2 3)

If the Scheme expression yields multiple values (see Multiple values), they are printed one by one.

gosh> (min&max 1 -1 8 3)

The history variable *1, *2 and *3 only binds the first value. A list of all values are bound to *1+, *2+ and *3+.

gosh> *1
gosh> *2+
(-1 8)

(Note that, when you evaluate *1 in the above example, the history is shifted—so you need to use *2+ to refer to the result of (min&max 1 -1 8 3).)

The *history procedure shows the value of history variables:

gosh> (*history)
*1: (-1 8)
*2: -1
*3: -1

As a special case, if an evaluation yields zero values, history isn’t updated. The *history procedure returns no values, so merely looking at the history won’t change the history itself.

gosh> (*history)
*1: (-1 8)
*2: -1
*3: -1
gosh> (values)
gosh> (*history)
*1: (-1 8)
*2: -1
*3: -1

Finally, a global variable *e is bound to the last uncaught error condition object.

gosh> (filter odd? ’(1 2 x 4 5))
*** ERROR: integer required, but got x
Stack Trace:
  0  (eval expr env)
        At line 173 of "/usr/share/gauche-0.9/"
gosh> *e
#<error "integer required, but got x">

(The error stack trace may differ depending on your installation.)

In REPL prompt, you can also enter special top-level commands for common tasks. Top-level commands are not Scheme expressions, not even S-expressions. They work like traditional line-oriented shell commands instead.

Top-level commands are prefixed by comma to be distinguished from ordinary Scheme expressions. To see what commands are available, just type ,help and return.

gosh> ,help
You're in REPL (read-eval-print-loop) of Gauche shell.
Type a Scheme expression to evaluate.
A word preceded with comma has special meaning.  Type ,help <cmd> 
to see the detailed help for <cmd>.
Commands can be abbreviated as far as it is not ambiguous.

 ,apropos|a  Show the names of global bindings that match the regexp.
 ,cd         Change the current directory.
 ,describe|d Describe the object.
 ,help|h     Show the help message of the command.
 ,history    Show REPL history.
 ,info|doc   Show info document for an entry of NAME, or search entries by REGEXP.
 ,load|l     Load the specified file.
             Print previous result (*1) without abbreviation.
             View/set print-mode of REPL.
 ,pwd        Print working directory.
 ,reload|r   Reload the specified module, using gauche.reload.
 ,sh         Run command via shell.
 ,source     Show source code of the procedure if it's available.
 ,use|u      Use the specified module.  Same as (use module option ...).

To see the help of each individual commands, give the command name (without comma) to the help command:

gosh> ,help d
Usage: d|describe [object]
Describe the object.
Without arguments, describe the last REPL result.

The ,d (or ,describe) top-level command describes the given Scheme object or the last result if no object is given. Let’s try some:

gosh> (sys-stat "/home")
#<<sys-stat> 0x2d6adc0>
gosh> ,d
#<<sys-stat> 0x2d6adc0> is an instance of class <sys-stat>
  type      : directory
  perm      : 493
  mode      : 16877
  ino       : 2
  dev       : 2081
  rdev      : 0
  nlink     : 9
  uid       : 0
  gid       : 0
  size      : 208
  atime     : 1459468837
  mtime     : 1401239524
  ctime     : 1401239524

In the above example, first we evaluated (sys-stat "/home"), which returns <sys-stat> object. The subsequent ,d top-level command describes the returned <sys-stat> object.

The description depends on the type of objects. Some types of objects shows extra information. If you describe an exact integer, it shows alternative interpretations of the number:

gosh> ,d 1401239524
1401239524 is an instance of class <integer>
  (#x538537e4, ~ 1.3Gi, 2014-05-28T01:12:04Z as unix-time)
gosh> ,d 48
48 is an instance of class <integer>
  (#x30, #\0 as char, 1970-01-01T00:00:48Z as unix-time)

If you describe a symbol, its known bindings is shown.

gosh> ,d 'filter
filter is an instance of class <symbol>
Known bindings for variable filter:
  In module `gauche':
    #<closure (filter pred lis)>
  In module `gauche.collection':
    #<generic filter (2)>

If you describe a procedure, and its source code location is known, that is also shown (see the Defined at... line):

gosh> ,d string-interpolate
#<closure (string-interpolate str :optional (legacy? #f))> is an
instance of class <procedure>
Defined at "../lib/gauche/interpolate.scm":64
  required  : 1
  optional  : #t
  optcount  : 1
  locked    : #f
  currying  : #f
  constant  : #f
  info      : (string-interpolate str :optional (legacy? #f))
  setter    : #f

Let’s see a couple of other top-level commands. The ,info command shows the manual entry of the given procedure, variable, syntax, module or a class. (The text is searched from the installed info document of Gauche. If you get an error, check if the info document is properly installed.)

gosh> ,info append
 -- Function: append list ...
     [R7RS] Returns a list consisting of the elements of the first LIST
     followed by the elements of the other lists.  The resulting list is
     always newly allocated, except that it shares structure with the
     last list argument.  The last argument may actually be any object;
     an improper list results if the last argument is not a proper list.

gosh> ,info srfi-19
 -- Module: srfi-19
     This SRFI defines various representations of time and date, and
     conversion methods among them.

     On Gauche, time object is supported natively by '<time>' class
     (*note Time::).  Date object is supported by '<date>' class
     described below.

gosh> ,info <list>
 -- Builtin Class: <list>
     An abstract class represents lists.  A parent class of '<null>' and
     '<pair>'.  Inherits '<sequence>'.

     Note that a circular list is also an instance of the '<list>'
     class, while 'list?' returns false on the circular lists and dotted
          (use srfi-1)
          (list? (circular-list 1 2)) => #f
          (is-a? (circular-list 1 2) <list>) => #t

You can also give a regexp pattern to ,info command (see Regular expressions). It shows the entries in the document that match the pattern.

gosh> ,info #/^string-.*\?/
string-ci<=?             Full string case conversion:44
                         String Comparison:19
string-ci<?              Full string case conversion:43
                         String Comparison:18
string-ci=?              Full string case conversion:42
                         String Comparison:17
string-ci>=?             Full string case conversion:46
                         String Comparison:21
string-ci>?              Full string case conversion:45
                         String Comparison:20
string-immutable?        String Predicates:9
string-incomplete?       String Predicates:12
string-null?             SRFI-13 String predicates:6
string-prefix-ci?        SRFI-13 String Prefixes & Suffixes:28
string-prefix?           SRFI-13 String Prefixes & Suffixes:26
string-suffix-ci?        SRFI-13 String Prefixes & Suffixes:29
string-suffix?           SRFI-13 String Prefixes & Suffixes:27

The ,a command (or ,apropos) shows the global identifiers matches the given name or regexp:

gosh> ,a filter
filter                         (gauche)
filter!                        (gauche)
filter$                        (gauche)
filter-map                     (gauche)

Note: The apropos command looks for symbols from the current process—that is, it only shows names that have been loaded and imported. But it also mean it can show any name as far as it exists in the current process, regardless of whether it’s a documented API or an internal entry.

On the other hand, the info command searches info document, regardless of the named entity has loaded into the current process or not. It doesn’t show undocumented APIs.

You can think that apropos is an introspection tool, while info is a document browsing tool.

When the result of evaluation is a huge nested structure, it may take too long to display the result. Gauche actually set a limit of length and depth in displaying structures, so you might occasionally see the very long or deep list is trucated, with … to show there are more items. (Try evaluating (make-list 100) on REPL).

You can type ,pa (or ,print-all) toplevel REPL command to fully redisplay the previous result without omission.

By default, REPL prints out the result using pretty print:

gosh> ,u sxml.ssax
gosh> (call-with-input-file "src/Info.plist" (cut ssax:xml->sxml <> '()))
 (*PI* xml "version=\"1.0\" encoding=\"UTF-8\"")
  (|@| (version "1.0"))
  (dict (key "CFBundleDevelopmentRegion") (string "English")
   (key "CFBundleExecutable") (string "Gauche") (key "CFBundleIconFile")
   (string) (key "CFBundleIdentifier") (string "com.schemearts.gauche")
   (key "CFBundleInfoDictionaryVersion") (string "6.0")
   (key "CFBundlePackageType") (string "FMWK") (key "CFBundleSignature")
   (string "????") (key "CFBundleVersion") (string "1.0")
   (key "NSPrincipalClass") (string))))

If you want to turn off pretty printing for some reason, type ,pm pretty #f (or ,print-mode pretty #f) on the toplevel prompt, or start gosh with the environment variable GAUCHE_REPL_NO_PPRINT set.

Type ,pm default to make print mode back to default. For more details, type ,help pm.

Note: If you invoke gosh with -q option, which tells gosh not to load the initialization files, you still get a REPL prompt but no fancy features such as history variables are available. Those convenience features are implemented in gauche.interactive module, which isn’t loaded with -q option.

Previous: , Up: Interactive development   [Contents][Index]