LIPS-scheme / lips

Scheme based powerful lisp interpreter in JavaScript
https://lips.js.org
Other
427 stars 35 forks source link

Add define-library example #371

Open Risto-Stevcev opened 3 months ago

Risto-Stevcev commented 3 months ago

Is there an example of using define-library and import? I know it's still in beta.

I wrote a swank-like repl server for LIPS, Risto-Stevcev/lips-repl-server@4798018, you can use it with emacs geiser as well. I wanted to make it more swank-like, so that the user imports it from a library, and runs a macro that creates the boilerplate in whatever module they're working on, with the call to the macro at the end of the file,, so that everything they need is in scope when they open up geiser and start working on that module.

jcubic commented 3 months ago

No. I didn't even realize that experimental define-library is part of the code.

I was reading the code, it was not working but found a bug. You need to update this function:

(define (new-library name namespace)
  "(new-library name)

   Create new empty library object with empty namespace."
  (let* ((parent (. (current-environment) '__parent__))
         (lib (let ((lib (--> parent (get name &(:throwError #f)))))
                (if (null? lib)
                    (new %Library name)
                    lib)))
         (x (new lips.Environment
                 (string-append "library-"
                                (--> name (toLowerCase))
                                "-"
                                (--> namespace (toLowerCase))))))
    (lib.append namespace x)
    lib))

The old code used false (in &(:throwError false)), but false no longer a parser constant so object literal was creating a string not the value false, and it was throwing an error when trying to check if the library already exists. Another issue is that (import (only ...)) doesn't work.

So after you add above code, you can use this:

(define-library (foo (bar))
  (define (_print message)
     (display message)
     (newline))
  (define (hello)
     (_print "hello, world"))
  (define (bye)
     (_print "bye"))
  (export hello)
  (export bye))

(import (foo bar))

(hello)
(bye)

I will update the code so at least what it's in the code do work.

Also note that this code only work inside same session, define-library creates an instance of an object. There are no modules of any kind, so you can't import a file.