Version: 0.0.54 (alpha)
The use of rapid prototyping enables early review and earlier discovery of problems. The sooner you get feedback, the more time you have to fix things and the higher the quality of the final product.
-- Kent Pitman, Accelerationg Hindsight: Lisp as a Vehicle for Rapid Prototyping
Lisp is still the best prototyping language. We need to push this forward.
-- Richard P. Gabriel (1991), Lisp: Good News, Bad News, How to Win Big
What programmers in a hundred years will be looking for, most of all, is a language where you can throw together an unbelievably inefficient version 1 of a program with the least possible effort.
-- Paul Graham, The Hundred-Year Language
CL+ is an Interface on Common Lisp for Rapid Prototyping. The goal of this project is not to create a new lisp dialect, nor to become a new utility collection. Instead, the goal of CL+ is a modern interface on CL for making inefficient ver.1 program, quickly. Removing CL+ layer on CL, we are able to optimize inefficient ver.1 program to efficient ver.2 program.
We need your feedback for improvement.
- Read-macros: ^, #{} and #[].
- Abstract data types: SEQUENS, TABULA and BUXIS.
- Lazy data structures: PROMISE, PIPE, LAZY-SEQUENCE and LAZY-FLOW.
- Sub-Packages:
- Core: LAZY-SEQUENCE, SEQUENS, TABULA, BUXIS, ...
- Library: CDR-5, CDR-8, CLRFI-1, SRFI-45 and SRFI-41, ...
- Extensible Polymorphic Operators: TO, REF, ADD, COPY, EMPTYP, SIZE, EQUALS and COMPARE.
- Utilities for Functional Programming Style:
$, $ *, <<, >>, &, v.
For more details, please see cl-plus/doc/features.md, cl-plus/doc/compare-with-cl.md.
;; Church style:
* (mapcar ^xy(+ x y) '(1 2 3) '(41 40 39)) => (42 42 42)
* (mapcar ^x0.y0(+ x0 y0) '(1 2 3) '(41 40 39)) => (42 42 42)
;; Hickey style:
* (funcall ^(if (< 100 @)
(- @ 10)
(@me (@me (+ @ 11))))
(random 102))
=> 91
;; Lazy-Sequence:
* (induce ^xyz(+ x y z) 0 0 1) => #[0 0 1 ..]
* (take 10 *) => (0 0 1 1 2 4 7 13 24 44)
* ** => #[0 0 1 1 2 4 7 13 24 44 ..]
* (take 10 #[0 ..]) => (0 1 2 3 4 5 6 7 8 9)
* (take 10 #[0 3 ..]) => (0 3 6 9 12 15 18 21 24 27)
* (take 10 #[1 2 4 ..]) => (1 2 4 8 16 32 64 128 256 512)
* (take :all #[1 .. 10]) => (1 2 3 4 5 6 7 8 9 10)
* (take :all #[#\a .. #\z] 'string) => "abcdefghijklmnopqrstuvwxyz"
* (reduce* '+ #[1..100]) => 5050
* (take 10 (lazy-for x from 1 by 2)) => (1 3 5 7 9 11 13 15 17 19)
* (take 10 (lazy-for (* x x)
(x from 1 by 2 when ^(zerop (mod @ 3)))))
=> (9 81 225 441 729 1089 1521 2025 2601 3249)
;; LFOR is just an alias for LAZY-FOR:
* (take 6 (lfor (cons x y)
(x replicate :foo :bar :baz :quux)
(y in #[1 2 4 ..])))
=> ((:FOO . 1) (:BAR . 2) (:BAZ . 4) (:QUUX . 8) (:FOO . 16) (:BAR . 32))
* #{:foo 0 :bar 1 :baz 2} => #{:foo 0 :bar 1 :baz}
* (hash-table-test #{:foo 0}) => EQUAL
* (hash-table-test #2{:foo 0}) => EQ
* (hash-table-test #3{:foo 0}) => EQL
* (hash-table-test #5{:foo 0}) => EQUAL
* (hash-table-test #6{:foo 0}) => EQUALP
* (map* t '1+ #{:foo 0 :bar 1 :baz 2 :quux 3})
=> #{:BAR 2 :BAZ 3 :QUUX 4 :FOO 1}
* (reduce* '+ #{:foo 0 :bar 1 :baz 2 :quux 3})
=> 6
* (take :all (remove-if* 'evenp #[0..20]))
=> (1 3 5 7 9 11 13 15 17 19)
* (remove-if* 'evenp #{:foo 0 :bar 1 :baz 2 :quux 3})
=> #{:BAR 1 :QUUX 3}
* (collect-if* 'evenp #[0..] :from 10 :count 4)
=> (10 12 14 16)
* (remove-if-not+ ^kv(and (oddp v) (= 3 (length (string k))))
#{:foo 0 :bar 1 :baz 2 :quux 3})
=> #{:BAR 1}
* (remove-if-not+ ^kv(and (oddp v) (= 3 (length (string k))))
'(:foo 0 :bar 1 :baz 2 :quux 3))
=> (:BAR 1)
* (remove-if-not+ ^kv(and (oddp v) (= 3 (length (string k))))
'((:foo . 0) (:bar . 1) (:baz . 2) (:quux . 3)))
=> ((:BAR . 1))
;; ADD, generailzed CONCATENATE.
* (add "Li" '(#\s #\p)) => "Lisp"
* (add #{:Roma "Varro"} #{:Carthage "Hannibal"})
=> #{:ROMA "Varro" :CARTHAGE "Hannibal"}
* (add * #{:Roma "Scipio"})
=> #{:ROMA "Scipio" :CARTHAGE "Hannibal"}
* (apply #'add (interpose ", " '("lazy" "delay" "eager")))
=> "lazy, delay, eager"
;; TO, generailzed COERCE.
* (to 'list "string") => (#\s #\t #\r #\i #\n #\g)
* (let ((txt (to 'string #p"./.gitignore")))
(subseq txt 0 (position #\Newline txt)))
=> "*.fasl"
;; SRFI-45: Primitives for Expressing Iterative Lazy Algorithms.
* (use-package :cl+srfi-45)
* (defvar *the-answer*
(delay (+ 1 3 5 9 11 13))) => *THE-ANSWER*
* *the-answer* => [?]
* (promisep *the-answer*) => T
* (force *the-answer*) => 42
* *the-answer* => [42]
;; Function Application: $, $*
* ($ repeat 2 $* * $ mapcar ^(* @ 3) $ mapcar 'max '(1 2) '(4 5))
=> (180 180)
* ($* * $ mapcar ^(* @ 3) $ mapcar 'max '(1 2) '(4 5))
=> 180
;; Composition: <<, >>
* (defun caesar-encode (shift text)
(map 'string (<< code-char _ + shift _ char-code)
text))
* (caesar-encode 3 "VENI VIDI VICI") => "YHQL#YLGL#YLFL"
* (defun caesar-decode (shift text)
(map 'string (>> char-code _ - shift _ code-char)
text))
* (caesar-decode 3 "YHQL#YLGL#YLFL") => "VENI VIDI VICI"
;; Conjoin, Disjoin: &, v
* (collect-if* (& integerp _ (v plusp _ < -10))
'(42 3.9 -3 -66 -9))
=> (42 -66)
-
CL-PLUS
- alexandria
- split-sequence
- named-readtables
- trivial-types
-
CL-PLUS-TEST
- cl-plus
- fiveam
- trivial-timeout
- trivial-features
- SHELL$
cd /path-to-quicklisp/quicklisp/local-projects/
- SHELL$
git clone https://github.com/tkych/cl-plus
- CL-USER>
(ql:quickload :cl-plus)
- CL-USER>
(in-package :cl+user)
- CL+USER>
(named-readtables:in-readtable :cl+)
; for ^, #{}, #[] - CL+USER>
(setf *print-pprint-dispatch* *cl+pprint-dispatch-table*)
; for print #{} - CL+USER>
(setf *print-pretty* t)
; for print #{}
or
- CL-USER>
(use-package <CL+SUB-PACKAGE-NAME>)
; e.g.,(use-package :cl+lazy-sequence)
or
- CL-USER>
(import <CL+SUB-PACKAGE-NAME>:<SYMBOL>)
; e.g.,(import 'cl+lazy-sequence:induce)
- CL-USER>
(ql:quickload :cl-plus-test)
- CL-USER>
(cl-plus-test:run-tests)
or(cl+t:run-tests)
If you don't need to run all tests, you can run only the particular suites by supplying the name of suite to run-tests
.
e.g., (cl+t:run-tests 'cl+t:?lazy-sequence 'cl+t:?lambda)
- Full tested: ccl, sbcl on linux.
- Partial tested: clisp, ecl, abcl on linux.
- Not tested yet: cmucl, allegro, lispworks, mocl, ...
- Please see package documentation for each file.
- Takaya OCHIAI <#.(reverse "moc.liamg@lper.hcykt")>
- The MIT License (see cl-plus/LICENSE for details)
- Copyright (c) 2014 Takaya OCHIAI
- Copyright (C) André van Tonder (2003) (for srfi-45.lisp).
- Copyright (C) Philip L. Bewig (2007) (for srfi-41.lisp).