Skip to content
forked from lice-lang/lice

A multi-paradigm programming language running on JVM

License

Notifications You must be signed in to change notification settings

KuzuryuYaichi/lice

 
 

Repository files navigation

Lice

CI status
Travis CI Build Status
AppVeyor Build status
CircleCI CircleCI
CodeShip Codeship Status for lice-lang/lice

JitPack
Gitter
Dependency Status
codecov
License: GPL v3
Awesome Kotlin Badge

About

This is the interpreter of Lice language, a dialect of Lisp, run on JVM platform.

It supports call-by-value, call-by-name, call-by-need(we sometimes call it lazy evaluation) at the same time. Functions and values are treated as the same. Dynamic scoping, because I can't find a better scoping solution for a interpreted language.

See FeatureTest to learn more about the language's features.

Also, as the main repo for the Lice language, this repo will not be updated very frequently.
Instead, I do language feature experiments in The tiny version of Lice, which is more actively updated and not guarenteed be backward capable.
Once a feature is finished and tested, and not considered harmful, I'll copy the codes here and publish releases.

It looks like

; print a string
(print "Hello " "World" "\n")

; travel through a range
(for-each i (.. 1 10) (print i "\n"))

; define a call-by-name function
(defexpr fold ls init op
 (for-each index-var ls
   (-> init (op init index-var))))

; invoke the function defined above
(fold (.. 1 4) 0 +)

; passing a call-by-value lambda to a call-by-value lambda
((lambda op (op 3 4)) (lambda a b (+ (* a a) (* b b))))

; to define a call-by-need lambda, use `lazy`.

Building

To use Lice with build tools, see JitPack instruction.

Alternatively, you can download the nightly jar for the newest commit on AppVeyor.

Script API

import javax.script.*;

public class LiceScriptEngineTest {
    public static void main() throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("lice");
        engine.eval("(-> x 10)");
        engine.eval("(print x)");
    }
}

Lice performance

Code to run:

; loops
(def loop count block (|>
    (-> i 0)
    (while (< i count) (|> (block i)
    (-> i (+ i 1))))))

; invoking the function
(loop 200000 (lambda i (|>
    (defexpr let x y block (|>
        (-> x y) ; this is actually an issue of lice.
        (block)
        (undef x)))
    (let reimu 100 (lambda (|> x))))))

(print "loop count: " i)

Environment: Ubuntu Linux 16.04, HotSpot 1.8u151, Intel core i7 4720HQ 2.6 GHz

Condition Time
Lice call Java using extern 350ms
Lice call Java using Lice API 295ms
Pure Java 13ms
Pure Lice 897ms
Java call Lice using Lice API 629ms

Lice invoking Java

Lice has handy APIs for interacting with Java.

; declare an extern function
; must be a static Java function
(extern "java.util.Objects" "equals")

; calling the extern function
(equals 1 1)

Java invoking Lice

This project provides handy APIs for running Lice codes from Java.

// Running Lice
System.out.println(Lice.run("(+ 1 1)")); // prints 2
System.out.println(Lice.run(new File("example.lice"))); // run codes in a file

// Lice API
SymbolList env = new SymbolList();
Lice.run("(def blablabla a (+ a a)) (-> myVar 233)", env);
env.extractLiceFunction("blablabla").invoke(233); // result: 466
int var = ((Number) env.extractLiceVariable("myVar")).intValue(); // result: 233

About

A multi-paradigm programming language running on JVM

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Kotlin 95.6%
  • Haskell 3.5%
  • Java 0.9%