Skip to content
/ LispEx Public
forked from kedebug/LispEx

A dialect of Lisp extended to support concurrent programming, written in Go.

License

Notifications You must be signed in to change notification settings

jsmorph/LispEx

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LispEx Build Status

A dialect of Lisp extended to support concurrent programming.

Overview

LispEx is another Lisp Interpreter implemented with Go. The syntax, semantics and library procedures are a subset of R5RS:

LispEx 0.1.0 (Saturday, 19-Jul-14 12:52:45 CST)

;; lambda expression
>>> ((lambda (x y . z) (+ x y (car z))) 1 2 5 11)
8

;; currying
>>> (define (curry func arg1) (lambda (arg) (apply func arg1 (list arg))))
>>> (map (curry + 2) '(1 2 3 4))
(3 4 5 6)

;; apply
>>> (apply + 1 2 '(3 4))
10

;; composite function
>>> (define ((compose f g) x) (f (g x)))
>>> (define caar (compose car car))
>>> (caar '((1 2) 3 4))
1

;; tail recursion 
>>> (letrec 
      ((even? (lambda (n) (if (= 0 n) #t (odd? (- n 1)))))
       (odd?  (lambda (n) (if (= 0 n) #f (even? (- n 1))))))
      (even? 88))
#t

;; multiple nestings of quasiquote 
;; (challenging to have a right implementation)
>>> `(1 `,(+ 1 ,(+ 2 3)) 4)
(1 `,(+ 1 5) 4)
>>> `(1 ```,,@,,@(list (+ 1 2)) 4)
(1 ```,,@,3 4)

;; lazy evaluation
>>> (define f (delay (+ 1)))
>>> (force f)
1

What's new, the Go-like concurrency features are introduced in LispEx. You can start new coroutines with go statements, and use <-chan or chan<- connecting them. A ping-pong example is shown below:

; define channels
(define ping-chan (make-chan))
(define pong-chan (make-chan))
; define a buffered channel
(define sem (make-chan 2))

(define (ping n)
  (if (> n 0)
    (begin
      (display (<-chan ping-chan))
      (newline)
      (chan<- pong-chan 'pong)
      (ping (- n 1)))
    (chan<- sem 'exit-ping)))

(define (pong n)
  (if (> n 0)
    (begin
      (chan<- ping-chan 'ping)
      (display (<-chan pong-chan))
      (newline)
      (pong (- n 1)))
    (chan<- sem 'exit-pong)))

(go (ping 6))  ; start ping-routine
(go (pong 6))  ; start pong-routine

; implement semaphore with channel, waiting for ping-pong finishing
(<-chan sem) (newline)
(<-chan sem) (newline)

; should close channels if you don't need it
(close-chan sem)
(close-chan pong-chan)
(close-chan ping-chan)

; the output will be: ping pong ping pong ... exit-ping exit-pong

Furthermore, select statement is also supported, which is necessary for you to select between multiple channels that working with concurrent routines. Just like Go, the code can be written like this:

(define chan-1 (make-chan))
(define chan-2 (make-chan))

(go (chan<- chan-1 'hello-chan-1))
(go (chan<- chan-2 'hello-chan-2))

(select
  ((<-chan chan-1))
  ((<-chan chan-2))
  (default 'hello-default))

(close-chan chan-1)
(close-chan chan-2)

; the output will be: hello-default, as it will cost some CPU times when a coroutine is lanuched.

In this scenario, default case is chosen since there is no ready data in chan-1 or chan-2 when select statement is intepretered. But such scenario will be changed if we sleep the main thread for a while:

(define chan-1 (make-chan))
(define chan-2 (make-chan))

(go (chan<- chan-1 'hello-chan-1))
(go (chan<- chan-2 'hello-chan-2))

; sleep for 20 millisecond
(sleep 20)

(select
  ((<-chan chan-1))
  ((<-chan chan-2))
  (default 'hello-default))

(close-chan chan-1)
(close-chan chan-2)

; the output will be randomized: hello-chan-1 or hello-chan-2

For more interesting examples, please see files under tests folder.

Features

  • Clean designed code, very easy for you to understand the principle, inspired from yin
  • A concurrent design for lexical scanning, inspired from Rob Pike
  • Builtin routines, channels and other necessary components for concurrent programming
  • Give you a REPL

In developing

  • loop in R5RS
  • tail call optimization
  • type checker

Have a try

git clone https://github.com/kedebug/LispEx.git
cd LispEx
go build && ./LispEx
LispEx 0.1.0 (Saturday, 19-Jul-14 12:52:45 CST)
>>> 

From here you can type in forms and you'll get the evaluated expressions back. To interpreter a file:

./LispEx filename.ss

Lisp is fun, go is fun, concurrency is fun. Hope you will have an extraordinary programming experience with LispEx.

License

MIT

About

A dialect of Lisp extended to support concurrent programming, written in Go.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 89.6%
  • Scheme 10.4%