diff options
author | Boris Verkhovskiy <boris.verk@gmail.com> | 2024-05-12 02:42:27 -0600 |
---|---|---|
committer | Boris Verkhovskiy <boris.verk@gmail.com> | 2024-05-12 02:48:10 -0600 |
commit | c7564c958c8b630b84bfd81ce01dd44d5fc48541 (patch) | |
tree | 1db7bc56bf8e60d70d3447be4066e82bae5b4eba /CHICKEN.html.markdown | |
parent | ff34febd6a954dfa78fbe5055ad0a4bf9bbfa964 (diff) |
Lowercase URLs
Diffstat (limited to 'CHICKEN.html.markdown')
-rw-r--r-- | CHICKEN.html.markdown | 517 |
1 files changed, 0 insertions, 517 deletions
diff --git a/CHICKEN.html.markdown b/CHICKEN.html.markdown deleted file mode 100644 index 37f6c859..00000000 --- a/CHICKEN.html.markdown +++ /dev/null @@ -1,517 +0,0 @@ ---- -language: "CHICKEN" -filename: CHICKEN.scm -contributors: - - ["Diwakar Wagle", "https://github.com/deewakar"] ---- - - -CHICKEN is an implementation of Scheme programming language that can -compile Scheme programs to C code as well as interpret them. CHICKEN -supports R5RS and R7RS (work in progress) standards and many extensions. - - -```scheme -;; #!/usr/bin/env csi -s - -;; Run the CHICKEN REPL in the commandline as follows : -;; $ csi - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 0. Syntax -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Single line comments start with a semicolon - -#| Block comments - can span multiple lines and... - #| can be nested - |# -|# - -;; S-expression comments are used to comment out expressions -#; (display "nothing") ; discard this expression - -;; CHICKEN has two fundamental pieces of syntax: Atoms and S-expressions -;; an atom is something that evaluates to itself -;; all builtin data types viz. numbers, chars, booleans, strings etc. are atoms -;; Furthermore an atom can be a symbol, an identifier, a keyword, a procedure -;; or the empty list (also called null) -'athing ;; => athing -'+ ;; => + -+ ;; => <procedure C_plus> - -;; S-expressions (short for symbolic expressions) consists of one or more atoms -(quote +) ;; => + ; another way of writing '+ -(+ 1 2 3) ;; => 6 ; this S-expression evaluates to a function call -'(+ 1 2 3) ;; => (+ 1 2 3) ; evaluates to a list - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 1. Primitive Datatypes and Operators -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Numbers -99999999999999999999 ;; integers -#b1010 ;; binary ; => 10 -#o10 ;; octal ; => 8 -#x8ded ;; hexadecimal ; => 36333 -3.14 ;; real -6.02e+23 -3/4 ;; rational - -;;Characters and Strings -#\A ;; A char -"Hello, World!" ;; strings are fixed-length arrays of characters - -;; Booleans -#t ;; true -#f ;; false - -;; Function call is written as (f x y z ...) -;; where f is a function and x,y,z, ... are arguments -(print "Hello, World!") ;; => Hello, World! -;; formatted output -(printf "Hello, ~a.\n" "World") ;; => Hello, World. - -;; print commandline arguments -(map print (command-line-arguments)) - -(list 'foo 'bar 'baz) ;; => (foo bar baz) -(string-append "pine" "apple") ;; => "pineapple" -(string-ref "tapioca" 3) ;; => #\i;; character 'i' is at index 3 -(string->list "CHICKEN") ;; => (#\C #\H #\I #\C #\K #\E #\N) -(string-intersperse '("1" "2") ":") ;; => "1:2" -(string-split "1:2:3" ":") ;; => ("1" "2" "3") - - -;; Predicates are special functions that return boolean values -(atom? #t) ;; => #t - -(symbol? #t) ;; => #f - -(symbol? '+) ;; => #t - -(procedure? +) ;; => #t - -(pair? '(1 2)) ;; => #t - -(pair? '(1 2 . 3)) ;; => #t - -(pair? '()) ;; => #f - -(list? '()) ;; => #t - - -;; Some arithmetic operations - -(+ 1 1) ;; => 2 -(- 8 1) ;; => 7 -(* 10 2) ;; => 20 -(expt 2 3) ;; => 8 -(remainder 5 2) ;; => 1 -(/ 35 5) ;; => 7 -(/ 1 3) ;; => 0.333333333333333 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 2. Variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; You can create variables with define -;; A variable name can use any character except: ()[]{}",'`;#\ -(define myvar 5) -myvar ;; => 5 - -;; Alias to a procedure -(define ** expt) -(** 2 3) ;; => 8 - -;; Accessing an undefined variable raises an exception -s ;; => Error: unbound variable: s - -;; Local binding -(let ((me "Bob")) - (print me)) ;; => Bob - -(print me) ;; => Error: unbound variable: me - -;; Assign a new value to previously defined variable -(set! myvar 10) -myvar ;; => 10 - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 3. Collections -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Pairs -;; 'cons' constructs pairs, -;; 'car' extracts the first element, 'cdr' extracts the rest of the elements -(cons 'subject 'verb) ;; => '(subject . verb) -(car (cons 'subject 'verb)) ;; => subject -(cdr (cons 'subject 'verb)) ;; => verb - -;; Lists -;; cons creates a new list if the second item is a list -(cons 0 '()) ;; => (0) -(cons 1 (cons 2 (cons 3 '()))) ;; => (1 2 3) -;; 'list' is a convenience variadic constructor for lists -(list 1 2 3) ;; => (1 2 3) - - -;; Use 'append' to append lists together -(append '(1 2) '(3 4)) ;; => (1 2 3 4) - -;; Some basic operations on lists -(map add1 '(1 2 3)) ;; => (2 3 4) -(reverse '(1 3 4 7)) ;; => (7 4 3 1) -(sort '(11 22 33 44) >) ;; => (44 33 22 11) - -(define days '(SUN MON FRI)) -(list-ref days 1) ;; => MON -(set! (list-ref days 1) 'TUE) -days ;; => (SUN TUE FRI) - -;; Vectors -;; Vectors are heterogeneous structures whose elements are indexed by integers -;; A Vector typically occupies less space than a list of the same length -;; Random access of an element in a vector is faster than in a list -#(1 2 3) ;; => #(1 2 3) ;; literal syntax -(vector 'a 'b 'c) ;; => #(a b c) -(vector? #(1 2 3)) ;; => #t -(vector-length #(1 (2) "a")) ;; => 3 -(vector-ref #(1 (2) (3 3)) 2);; => (3 3) - -(define vec #(1 2 3)) -(vector-set! vec 2 4) -vec ;; => #(1 2 4) - -;; Vectors can be created from lists and vice-verca -(vector->list #(1 2 4)) ;; => '(1 2 4) -(list->vector '(a b c)) ;; => #(a b c) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 4. Functions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Use 'lambda' to create functions. -;; A function always returns the value of its last expression -(lambda () "Hello World") ;; => #<procedure (?)> - -;; Use extra parens around function definition to execute -((lambda () "Hello World")) ;; => Hello World ;; argument list is empty - -;; A function with an argument -((lambda (x) (* x x)) 3) ;; => 9 -;; A function with two arguments -((lambda (x y) (* x y)) 2 3) ;; => 6 - -;; assign a function to a variable -(define sqr (lambda (x) (* x x))) -sqr ;; => #<procedure (sqr x)> -(sqr 3) ;; => 9 - -;; We can shorten this using the function definition syntactic sugar -(define (sqr x) (* x x)) -(sqr 3) ;; => 9 - -;; We can redefine existing procedures -(foldl cons '() '(1 2 3 4 5)) ;; => (((((() . 1) . 2) . 3) . 4) . 5) -(define (foldl func accu alist) - (if (null? alist) - accu - (foldl func (func (car alist) accu) (cdr alist)))) - -(foldl cons '() '(1 2 3 4 5)) ;; => (5 4 3 2 1) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 5. Equality -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; For numbers use '=' -(= 3 3.0) ;; => #t -(= 2 1) ;; => #f - -;; 'eq?' returns #t if two arguments refer to the same object in memory -;; In other words, it's a simple pointer comparison. -(eq? '() '()) ;; => #t ;; there's only one empty list in memory -(eq? (list 3) (list 3)) ;; => #f ;; not the same object -(eq? 'yes 'yes) ;; => #t -(eq? 3 3) ;; => #t ;; don't do this even if it works in this case -(eq? 3 3.0) ;; => #f ;; it's better to use '=' for number comparisons -(eq? "Hello" "Hello") ;; => #f - -;; 'eqv?' is same as 'eq?' all datatypes except numbers and characters -(eqv? 3 3.0) ;; => #f -(eqv? (expt 2 3) (expt 2 3)) ;; => #t -(eqv? 'yes 'yes) ;; => #t - -;; 'equal?' recursively compares the contents of pairs, vectors, and strings, -;; applying eqv? on other objects such as numbers and symbols. -;; A rule of thumb is that objects are generally equal? if they print the same. - -(equal? '(1 2 3) '(1 2 3)) ;; => #t -(equal? #(a b c) #(a b c)) ;; => #t -(equal? 'a 'a) ;; => #t -(equal? "abc" "abc") ;; => #t - -;; In Summary: -;; eq? tests if objects are identical -;; eqv? tests if objects are operationally equivalent -;; equal? tests if objects have same structure and contents - -;; Comparing strings for equality -(string=? "Hello" "Hello") ;; => #t - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 6. Control Flow -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Conditionals -(if #t ;; test expression - "True" ;; then expression - "False") ;; else expression - ;; => "True" - -(if (> 3 2) - "yes" - "no") ;; => "yes" - -;; In conditionals, all values that are not '#f' are treated as true. -;; 0, '(), #() "" , are all true values -(if 0 - "0 is not false" - "0 is false") ;; => "0 is not false" - -;; 'cond' chains a series of tests and returns as soon as it encounters a true condition -;; 'cond' can be used to simulate 'if/elseif/else' statements -(cond ((> 2 2) "not true so don't return this") - ((< 2 5) "true, so return this") - (else "returning default")) ;; => "true, so return this" - - -;; A case expression is evaluated as follows: -;; The key is evaluated and compared with each datum in sense of 'eqv?', -;; The corresponding clause in the matching datum is evaluated and returned as result -(case (* 2 3) ;; the key is 6 - ((2 3 5 7) 'prime) ;; datum 1 - ((1 4 6 8) 'composite)) ;; datum 2; matched! - ;; => composite - -;; case with else clause -(case (car '(c d)) - ((a e i o u) 'vowel) - ((w y) 'semivowel) - (else 'consonant)) ;; => consonant - -;; Boolean expressions -;; 'and' returns the first expression that evaluates to #f -;; otherwise, it returns the result of the last expression -(and #t #f (= 2 2.0)) ;; => #f -(and (< 2 5) (> 2 0) "0 < 2 < 5") ;; => "0 < 2 < 5" - -;; 'or' returns the first expression that evaluates to #t -;; otherwise the result of the last expression is returned -(or #f #t #f) ;; => #t -(or #f #f #f) ;; => #f - -;; 'when' is like 'if' without the else expression -(when (positive? 5) "I'm positive") ;; => "I'm positive" - -;; 'unless' is equivalent to (when (not <test>) <expr>) -(unless (null? '(1 2 3)) "not null") ;; => "not null" - - -;; Loops -;; loops can be created with the help of tail-recursions -(define (loop count) - (unless (= count 0) - (print "hello") - (loop (sub1 count)))) -(loop 4) ;; => hello, hello ... - -;; Or with a named let -(let loop ((i 0) (limit 5)) - (when (< i limit) - (printf "i = ~a\n" i) - (loop (add1 i) limit))) ;; => i = 0, i = 1.... - -;; 'do' is another iteration construct -;; It initializes a set of variables and updates them in each iteration -;; A final expression is evaluated after the exit condition is met -(do ((x 0 (add1 x ))) ;; initialize x = 0 and add 1 in each iteration - ((= x 10) (print "done")) ;; exit condition and final expression - (print x)) ;; command to execute in each step - ;; => 0,1,2,3....9,done - -;; Iteration over lists -(for-each (lambda (a) (print (* a a))) - '(3 5 7)) ;; => 9, 25, 49 - -;; 'map' is like for-each but returns a list -(map add1 '(11 22 33)) ;; => (12 23 34) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 7. Extensions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; The CHICKEN core is very minimal, but additional features are provided by library extensions known as Eggs. -;; You can install Eggs with 'chicken-install <eggname>' command. - -;; complex numbers -3+4i ;; => 3+2i -;; Supports fractions without falling back to inexact flonums -1/3 ;; => 1/3 -;; provides support for large integers through bignums -(expt 9 20) ;; => 12157665459056928801 -;; And other 'extended' functions -(log 10 (exp 1)) ;; => 2.30258509299405 -(numerator 2/3) ;; => 2 - -;; 'utf8' provides unicode support -(import utf8) -"\u03BBx:(\u03BC\u0251.\u0251\u2192\u0251).xx" ;; => "λx:(μɑ.ɑ→ɑ).xx" - -;; 'posix' provides file I/O and lots of other services for unix-like operating systems -;; Some of the functions are not available in Windows system, -;; See http://wiki.call-cc.org/man/5/Module%20(chicken%20file%20posix) for more details - -;; Open a file to append, open "write only" and create file if it does not exist -(define outfn (file-open "chicken-hen.txt" (+ open/append open/wronly open/creat))) -;; write some text to the file -(file-write outfn "Did chicken came before hen?") -;; close the file -(file-close outfn) -;; Open the file "read only" -(define infn (file-open "chicken-hen.txt" open/rdonly)) -;; read some text from the file -(file-read infn 30) ;; => ("Did chicken came before hen? ", 28) -(file-close infn) - -;; CHICKEN also supports SRFI (Scheme Requests For Implementation) extensions -;; See 'http://srfi.schemers.org/srfi-implementers.html" to see srfi's supported by CHICKEN -(import srfi-1) ;; list library -(filter odd? '(1 2 3 4 5 6 7)) ;; => (1 3 5 7) -(count even? '(1 2 3 4 5)) ;; => 2 -(take '(12 24 36 48 60) 3) ;; => (12 24 36) -(drop '(12 24 36 48 60) 2) ;; => (36 48 60) -(circular-list 'z 'q) ;; => z q z q ... - -(import srfi-13) ;; string library -(string-reverse "pan") ;; => "nap" -(string-index "Turkey" #\k) ;; => 3 -(string-every char-upper-case? "CHICKEN") ;; => #t -(string-join '("foo" "bar" "baz") ":") ;; => "foo:bar:baz" - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 8. Macros -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; A 'for .. in ..' iteration like python, for lists -(define-syntax for - (syntax-rules (in) - ((for elem in alist body ...) - (for-each (lambda (elem) body ...) alist)))) - -(for x in '(2 4 8 16) - (print x)) ;; => 2, 4, 8, 16 - -(for chr in (string->list "PENCHANT") - (print chr)) ;; => P, E, N, C, H, A, N, T - -;; While loop -(define-syntax while - (syntax-rules () - ((while cond body ...) - (let loop () - (when cond - body ... - (loop)))))) - -(let ((str "PENCHANT") (i 0)) - (while (< i (string-length str)) ;; while (condition) - (print (string-ref str i)) ;; body - (set! i (add1 i)))) - ;; => P, E, N, C, H, A, N, T - -;; Advanced Syntax-Rules Primer -> http://petrofsky.org/src/primer.txt -;; Macro system in chicken -> http://lists.gnu.org/archive/html/chicken-users/2008-04/msg00013.html - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 9. Modules -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Also See http://wiki.call-cc.org/man/5/Modules - -;; The 'test' module exports a value named 'hello' and a macro named 'greet' -(module test (hello greet) - (import scheme) - - (define-syntax greet - (syntax-rules () - ((_ whom) - (begin - (display "Hello, ") - (display whom) - (display " !\n") ) ) ) ) - - (define (hello) - (greet "world") ) ) - -;; we can define our modules in a separate file (say test.scm) and load them to the interpreter with -;; (load "test.scm") - -;; import the module -(import test) -(hello) ;; => Hello, world ! -(greet "schemers") ;; => Hello, schemers ! - -;; We can compile the module files in to shared libraries by using following command, -;; csc -s test.scm -;; (load "test.so") - -;; Functors -;; Functors are high level modules that can be parameterized by other modules -;; Following functor requires another module named 'M' that provides a function called 'multiply' -;; The functor itself exports a generic function 'square' -(functor (squaring-functor (M (multiply))) (square) - (import scheme M) - (define (square x) (multiply x x))) - -;; Module 'nums' can be passed as a parameter to 'squaring-functor' -(module nums (multiply) - (import scheme) ;; predefined modules - (define (multiply x y) (* x y))) -;; the final module can be imported and used in our program -(module number-squarer = (squaring-functor nums)) - -(import number-squarer) -(square 3) ;; => 9 - -;; We can instantiate the functor for other inputs -;; Here's another example module that can be passed to squaring-functor -(module stars (multiply) - (import chicken scheme) ;; chicken module for the 'use' keyword - (use srfi-1) ;; we can use external libraries in our module - (define (multiply x y) - (list-tabulate x (lambda _ (list-tabulate y (lambda _ '*)))))) -(module star-squarer = (squaring-functor stars)) - -(import star-squarer) -(square 3) ;; => ((* * *)(* * *)(* * *)) -``` - -## Further Reading -* [CHICKEN User's Manual](https://wiki.call-cc.org/manual). -* [R5RS standards](http://www.schemers.org/Documents/Standards/R5RS) - - -## Extra Info - -* [For programmers of other languages](https://wiki.call-cc.org/chicken-for-programmers-of-other-languages) -* [Compare CHICKEN syntax with other languages](http://plr.sourceforge.net/cgi-bin/plr/launch.py) |