CljPerl - A lisp on perl.
(defmacro defn [name args & body] `(def ~name (fn ~args ~@body))) (defn foo [arg] (println arg)) (foo "hello world!") ;comment here
CljPerl is a lisp implemented by Perl. It borrows the idea from Clojure, which makes a seamless connection with Java packages. Like Java, Perl has huge number of CPAN packages. They are amazing resources. We should make use of them as possible. However, programming in lisp is more insteresting. CljPerl is a bridge between lisp and perl. We can program in lisp and make use of the great resource from CPAN.
CljPerl is hosted on Perl. Any object of CljPerl can be passed into Perl and vice versa including code.
An example of using Perl's IO functions.
package CljPerl; sub open { my $file = shift; my $cb = shift; my $fh; open $fh, $file; &{$cb}($fh); close $fh; } sub puts { my $fh = shift; my $str = shift; print $fh $str; } sub readline { my $fh = shift; return <$fh>; }
(ns file (defn open [file cb] (. open file cb)) (defn >> [fh str] (. puts fh str)) (defn << [fh] (. readline fh)))
(file#open ">t.txt" (fn [f] (file#>> f "aaa"))) (file#open "<t.txt" (fn [f] (println (perl->clj (file#<< f)))))
An advanced example which creates a timer with AnyEvent.
(. require AnyEvent) (def cv (->AnyEvent condvar)) (def count 0) (def t (->AnyEvent timer {:after 1 :interval 1 :cb (fn [ & args] (println count) (set! count (+ count 1)) (if (>= count 10) (set! t nil)))})) (.AnyEvent::CondVar::Base recv cv)
* Reader forms * Symbols : foo, foo#bar * Literals * Strings : "foo", "\"foo\tbar\n\"" * Numbers : 1, -2, 2.5 * Booleans : true, false * Keywords : :foo * Lists : (foo bar) * Vectors : [foo bar] * Maps : {:key1 value1 :key2 value2 "key3" value3}
* Quote (') : '(foo bar) * Comment (;) : ; comment * Dispatch (#) : * Accessor (:) : #:0 ; index accessor #:"key" ; key accessor #::key ; key accessor * Sender (!) : #!"foo" * XML ([) : #[body ^{:attr "value"}] * Metadata (^) : ^{:key value} * Syntax-quote (`) : `(foo bar) * Unquote (~) : `(foo ~bar) * Unquote-slicing (~@) : `(foo ~@bar)
* list : (list 'a 'b 'c) ;=> '(a b c) * car : (car '(a b c)) ;=> 'a * cdr : (cdr '(a b c)) ;=> '(b c) * cons : (cons 'a '(b c)) ;=> '(a b c) * key accessor : (#::a {:a 'a :b 'a}) ;=> 'a * keys : (keys {:a 'a :b 'b}) ;=> (:a :b) * index accessor : (#:1 ['a 'b 'c]) ;=> 'b * sender : (#:"foo" ['a 'b 'c]) ;=> (foo ['a 'b 'c]) * xml : #[html ^{:class "markdown"} #[body "helleworld"]] * length : (length '(a b c)) ;=> 3 (length ['a 'b 'c]) ;=> 3 (length "abc") ;=> 3 * append : (append '(a b) '(c d)) ;=> '(a b c d) (append ['a 'b] ['c 'd]) ;=> ['a 'b 'c 'd] (append "ab" "cd") ;=> "abcd" * type : (type "abc") ;=> "string" (type :abc) ;=> "keyword" (type {}) ;=> "map" * meta : (meta foo ^{:m 'b}) (meta foo) ;=> {:m 'b} * fn : (fn [arg & args] (println 'a)) * apply : (apply list '(a b c)) ;=> '(a b c) * eval : (eval "(+ 1 2)") * require : (require "core") * def : (def foo "bar") (def ^{:k v} foo "bar") * set! : (set! foo "bar") * let : (let [a 1 b a] (println b)) * defmacro : (defmacro foo [arg & args] `(println ~arg) `(list ~@args)) * if : (if (> 1 0) (println true) (println false)) (if true (println true)) * while : (while true (println true)) * begin : (begin (println 'foo) (println 'bar)) * perl->clj : * ! : (! true) ;=> false * + - * / % == != >= <= > < : only for number. * eq ne : only for string. * equal : for all objects. * . : (.[perl namespace] method [^meta] args ...) A meta can be specifed to control what type of value should be passed into perl function. type : "scalar" "array" "hash" "ref" "nil" ^{:return type :arguments [type ...]} (.CljPerl print "foo") (.CljPerl print ^{:return "nil" :arguments ["scalar"]} "foo") ; return nil and pass first argument as a scalar * -> : (->[perl namespace] method args ...) Like '.', but this will pass perl namespace as first argument to perl method. * println (println {:a 'a}) * trace-vars : Trace the variables in current frame. (trace-vars)
* use-lib : append path into Perl and CljPerl files' searching paths. (use-lib "path") * ns : CljPerl namespace. (ns "foo" (println "bar")) * defn : (defn foo [arg & args] (println arg)) * defmulti : * defmethod : * reduce : * map : * file#open : open a file with a callback. (file#open ">file" (fn [fh] (file#>> fn "foo"))) * file#<< : read a line from a file handler. (file#<< fh) * file#>> : write a string into a file handler. (file#>> fh "foo")
Wei Hu, <huwei04@hotmail.com>
Copyright 2013 Wei Hu. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
To install CljPerl, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CljPerl
CPAN shell
perl -MCPAN -e shell install CljPerl
For more information on module installation, please visit the detailed CPAN module installation guide.