GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — lispy/mylis at main · fluentpython/lispy

Expand file tree

/

mylis

/
Copy path

Directory actions

More options

More options

Directory actions

More options

More options

Latest commit

 

History

History
History
/

mylis

/
Copy path

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
mylis_1
mylis_1
 
 
mylis_1_closure
mylis_1_closure
 
 
mylis_2
mylis_2
 
 
mylis_3
mylis_3
 
 
README.md
README.md
 
 

README.md

Outline

Mylis: a tiny Scheme interpreter

Mylis is derived from a Python 3.10 fork of Peter Norvig's lis.py, adding some features for demonstration purposes.

There are two versions of Mylis:

  • mylis_1 is closer to the original lis.py. The main differences are usability features: an enhanced REPL and new command-line integration, both available through the mylis_1/mylis.py script. The mylis_1/lis.py module shows the use of pattern matching in the evaluate function.
  • mylis_2 has all the features of mylis_1 plus mutation with the set! command, and proper tail calls for efficient iteration through tail recursion. It is a step towards implementing the language features of Norvig's more advanced lispy.py.

Interactive use

Running mylis.py without arguments opens a REPL.

Mylis has limited error handling. Simple mistakes will crash the interpreter.

$ ./mylis.py
To exit type .q
▷  x
🚨  Undefined symbol: 'x'
▷  pi
3.141592653589793
▷  (/ pi 2)
1.5707963267948966
▷  (define (half x) (/ x 2))
▷  (cos (half pi))
6.123233995736766e-17
▷  (sin (half pi))
1.0
▷  (define (! n)
⋯    (if (< n 2)
⋯        1
⋯        (* n (! (- n 1)))
⋯    ))
▷  (! 5)
120
▷  (! 42)
1405006117752879898543142606244511569936384000000000
▷  .q
$

For longer experiments, use source files and command-line arguments, as presented next.

Command-line integration

You can run programs written in the supported Scheme subset from the command-line, like this:

./mylis.py examples/fibo-seq.scm n=20
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)

The n=20 option creates an n global variable with the given value.

If you read examples/fibo-seq.scm you'see that the last line is:

(display (fibo-seq n))

The n is not defined in the program, so it must be given as a command-line argument: n=...

Any command-line option with the syntax symbol=value will be interpreted as a global definition—with the limitation that value must be an integer or a float:

(define symbol value)

If you forget to provide a required argument, the interpreter will make a suggestion (but currently it stops at the first undefined variable found):

$ ./mylis.py examples/fibo-seq.scm
🚨  'n' was not defined.
    You can define it as an option:
    $ ./mylis.py examples/fibo-seq.scm n=<value>
$ ./mylis.py examples/fibo-seq.scm n=20
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)

LR

São Paulo, August 15, 2021

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.