Giter Club home page Giter Club logo

lips's Introduction

LIPS - Scheme Based Powerful Lisp Language

npm 1.0.0 Complete travis Coverage Status Join Gitter Chat NPM Download Count JSDelivr Download count FOSSA Status

GitHub stars Tweet

LIPS is a powerful Scheme-based, Lisp language written in JavaScript. It is based on the Scheme dialect and the R5RS/R7RS specifications. It has extensions to make it easier to interact with JavaScript. It work both in the browser and with Node.js.

The name is a recursive acronym which stands for LIPS Is Pretty Simple.

Demo

Web REPL Demo

Features

  • Literal regular expression.
  • Asynchronous execution (auto resolving of promises).
  • Possibility to add new syntax (similar to vectors and object).
  • Numerical tower and Big Integer support.
  • Powerful introspection.
  • Great integration with JavaScript.
  • Auto formatting lisp of code (pretty print)
  • Lisp and hygienic Scheme macros and macroexpand.
  • Builtin help system.

Installation

To install you can use npm (or yarn)
NOTE: The version that is on NPM is heavily outdated, use beta version:

npm install @jcubic/lips@beta

or yarn:

yarn add @jcubic/lips@beta

then include the file in the script tag. You can grab the version from unpkg.com

https://unpkg.com/@jcubic/lips@beta

or from jsDelivr (that's seems a bit faster)

https://cdn.jsdelivr.net/npm/@jcubic/lips@beta/dist/lips.min.js

Bookmarklet REPL

You can also run the REPL on any page while you learn Scheme using the bookmarklet:

https://github.com/jcubic/lips/blob/master/lib/js/bookmark.js

Create any link in your bookmarks, edit it and copy paste the content of that file. Affter you click on the link it will create the REPL at the bottom of the page. (NOTE: It may not work on every page because of content security policy; e.g. google.com or gihub.com)

If you have trouble with creating the bookmarklet you can open LISP Scheme home page where you can find a link that you can drag to your bookmarks.

Usage

The simplest way is to include the lips code in the script tag:

<script type="text/x-scheme" bootstrap>
(let ((what "world")
      (greet "hello"))
   (display (string-append greet " " what)))
</script>

or use the src attribute:

<script type="text/x-scheme" bootstrap src="example.scm"></script>

Bootstrapping Scheme system

Big part of LIPS is written in LIPS itself, but to use full power of LIPS you need to load those additional Scheme files. The easiest way is to add bootstrap attribute on first script tag with text/x-scheme type. By default it will use CDN from jsdelivr. To load each file using builtin load function (that will fetch the file using AJAX and evaluate it).

<script src="https://cdn.jsdelivr.net/npm/@jcubic/lips@beta/dist/lips.min.js" bootstrap></script>

You can also specify the path where LIPS should search for standard library.

<script src="https://cdn.jsdelivr.net/npm/@jcubic/lips@beta/dist/lips.min.js"
        bootstrap="https://cdn.jsdelivr.net/npm/@jcubic/lips@beta/dist/std.xcb">
</script>

You can use bootstrap="./std.xcb" if there is std.xcb file in local directory. You can also bootstrap with std.scm or std.min.scm but xcb file is the fastest, because it's already parsed and compiled into binary format.

Running LIPS programmatically

var {exec} = require('@jcubic/lips'); // node
// or
var {exec} = lips; // browser

exec(string).then(function(results) {
     results.forEach(function(result) {
        console.log(result.toString());
     });
});

When running exec you will also need to bootstrap the language and loaded files from /lib/ directory.

Documentation about beta version can be found in Wiki.

Standalone executable

NOTE: Executable don't require bootstrapping lib files.

If you install lips globally with:

npm install -g @jcubic/lips@beta

you can run the interpreter from the terminal:

LIPS: Scheme interactive terminal

You can also run code in a string with:

lips -c '(let ((what "World")) (display (string-append "Hello " what)))'

and you can run a file using:

cat > foo.scm <<EOF
(let ((what "World"))
  (display (string-append "Hello " what))
  (newline))
EOF

lips foo.scm

You can also write executable files that use lips using shebang (SRFI-22)

cat foo.scm
#!/usr/bin/env lips

(let ((what "World"))
  (display (string-append "Hello " what))
  (newline))

chmod a+x foo.scm
./foo.scm

Executables also return a S-Expression according to SRFI-176 use lips --version or lips -V.

FOSDEM'23 Presentation [Video]

FOSDEM 2023 - LIPS Scheme: Powerful introspection and extensibility

Limitations

Because LIPS is tree walking interpreter sometimes it may be slow. Especially if you want to process long arrays and use callback function. If the array is quite large each pice of code inside the callback may slow down the processing. For example see:

script reference.scm

That generates reference documentation for all builtin functions and macros. The slow part is (names.sort name-compare) (Array::sort) that take quite time to calculate, because the array with functions and macros is quite large. If you came into performance issue, you can write the part of the code in JavaScript. If you want to do this in LIPS Scheme you can use something like this:

(let ((fn (self.eval "(function(a, b) {
                         /* any complex code in JS */
                         return a.localeCompare(b);
                      })")))
   (arr.sort fn))

Another example of slow performace is using LIPS with React, the more code you put into components the slower the app will become.

Examples:

The issue with performance is tracked in #197.

Supported SRFI

built-in

description spec
Feature-based conditional expansion construct SRFI-0
Homogeneous numeric vector datatypes SRFI-4
Basic String Ports SRFI-6
Running Scheme Scripts on Unix SRFI-22
Error reporting mechanism SRFI-23
Basic Syntax-rules Extensions SRFI-46
Version flag SRFI-176

require (load "./lib/srfi/<number>.scm")

They should be loaded as R7RS libraries in final 1.0.0 version

description spec
List Library SRFI-1
AND-LET*: an AND with local bindings, a guarded LET* special form SRFI-2
receive: Binding to multiple values SRFI-8
#, external form SRFI-10
Notation for Specializing Parameters without Currying SRFI-26
Basic hash tables SRFI-69
An interface to access environment variables SRFI-98
Boxes SRFI-111
Syntactic combiners for binary predicates SRFI-156

Links

Roadmap

1.0

  • Full support for R5RS
  • Full support for R7RS
    • R7RS libraries (import/export/define-library).
    • Continuations.
    • Tail Call Optimization (TCO).
    • Fully tested Numerical Tower.
  • Fully working binary compiler (for faster parsing and loading std lib).
  • Finish syntax-rules (ignore limitations of current approach).
    • Objects.
    • Vectors.

1.1

  • Picture language (possibly inspired by P5.js).
  • Stepper/Debugger.
  • Allow to use read/port in syntax extensions (similar to CL reader macros).
  • Proper expansion time for both macro system.
  • Fully working and tested R7RS hygienic Macros (syntax-rules).
  • All recursive function in JS don't consume stack.

WIP Side projects

  • KISS (chrome extension REPL).
  • SMILE (Web IDE), need to start over.

Acknowledgments

License

Released under MIT license
Copyright (c) 2018-2021 Jakub T. Jankiewicz

FOSSA Status

lips's People

Contributors

jcubic avatar dependabot[bot] avatar snyk-bot avatar semitonegene avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.