quasiquote & unquote in scheme
> (define day-of-week 'Sunday)
> (define greet
(lambda ()
(quasiquote (Today is (unquote day-of-week)))))
> (greet)
(Today is Sunday)
> (set! day-of-week 'Monday)
> (greet)
(Today is Monday)
> (define day-of-week 'Sunday)
> (define greet
(lambda ()
(quasiquote (Today is (unquote day-of-week)))))
> (greet)
(Today is Sunday)
> (set! day-of-week 'Monday)
> (greet)
(Today is Monday)
;; Enable auto-pair
(setq skeleton-pair t)
(global-set-key "(" 'skeleton-pair-insert-maybe)
(global-set-key "[" 'skeleton-pair-insert-maybe)
(global-set-key "{" 'skeleton-pair-insert-maybe)
(global-set-key "\"" 'skeleton-pair-insert-maybe)
(global-set-key "'" 'skeleton-pair-insert-maybe)
;; Custom keybinding (defun duplicate-line() (interactive) (move-beginning-of-line 1) (kill-line) (yank) (open-line 1) (next-line 1) (yank) (next-line 1)) (global-set-key (kbd "C-d") 'duplicate-line)Now you quickly duplicate a line my pressing Ctrl+d.
#lang scheme
(require
(lib "trace.ss"))
(define (length list)
(if (null? list)
0
(+ (length (cdr list)) 1)))
(trace length)
(define (length-cps list)
(define (length-cps list continuation)
(if (null? list)
(continuation 0)
(length-cps (cdr list)
(lambda (v)
(continuation (+ v 1))))))
(length-cps list (lambda (v) v)))
(trace length-cps)
> (time (length (list 1 2 3 4 5)))
|(length (1 2 3 4 5))
| (length (2 3 4 5))
| |(length (3 4 5))
| | (length (4 5))
| | |(length (5))
| | | (length ())
| | | 0
| | |1
| | 2
| |3
| 4
|5
cpu time: 87 real time: 107 gc time: 61
5
> (time (length-cps (list 1 2 3 4 5)))
|(length-cps (1 2 3 4 5))
|5
cpu time: 6 real time: 6 gc time: 0
5
#lang scheme
(define fiber-list empty)
(define fiber
(lambda (fib)
(set! fiber-list (append fiber-list (list fib)))))
(define start
(lambda ()
(let ([p (car fiber-list)])
(set! fiber-list (cdr fiber-list))
(p))))
(define pause
(lambda ()
(call/cc (lambda (k)
(fiber (lambda () (k false)))
(start)))))
> (fiber (lambda () (let f () (pause) (display "g") (f))))
> (fiber (lambda () (let f () (pause) (display "a") (f))))
> (fiber (lambda () (let f () (pause) (display "n") (f))))
> (fiber (lambda () (let f () (pause) (display "e") (f))))
> (fiber (lambda () (let f () (pause) (display "s") (f))))
> (fiber (lambda () (let f () (pause) (display "h") (f))))
> (fiber (lambda () (let f () (pause) (newline) (f))))
> (start)
ganesh
ganesh
ganesh
(define continuation #f)
(define (hello)
(let ([i 0])
(display "Counter initialized")
(newline)
(call/cc (lambda (k) (set! continuation k)))
(set! i (+ 1 i))
i))
> (hello)
Counter initialized
1
> (continuation)
2
> (continuation)
3
> (continuation)
4
> (continuation)
5
(require
(lib "trace.ss"))
(define (len-iter list)
(define (len-iter list acc)
(cond
[(null? list) acc]
[else (len-iter (cdr list) (+ 1 acc))]))
(len-iter list 0))
(trace len-iter)
(define (len list)
(cond
[(null? list) 0]
[else (+ 1 (len (cdr list)))]))
(trace len)
Iterative style outperforms linear recursive style.
> (time (len (list 1 2 3 4 5))) |(len (1 2 3 4 5)) | (len (2 3 4 5)) | |(len (3 4 5)) | | (len (4 5)) | | |(len (5)) | | | (len ()) | | | 0 | | |1 | | 2 | |3 | 4 |5 cpu time: 41 real time: 82 gc time: 0 5 > (time (len-iter (list 1 2 3 4 5))) |(len-iter (1 2 3 4 5)) |5 cpu time: 6 real time: 7 gc time: 0 5
It is dead simple to add a syntactic extension to Scheme. The following is an if version without the else block.
(define-syntax iff
(syntax-rules ()
[(_ predicate arg)
(if predicate arg #f)]))
> (iff true "GG")
"GG"
> (iff false "GG")
#f
Of course, you can achieve the same effect using and syntactic core form
> (and true "GG") "GG" > (and false "GG") #f
(define lazy
(lambda (t)
(let ([val false] [flag false])
(lambda ()
(cond
[(not flag)
(begin (set! val (t))
(set! flag true))])
val))))
(define lazy-dude
(lazy (lambda()
(display "I am awake")
(newline)
"Yippee")))
> (lazy-dude) I am awake "Yippee" > (lazy-dude) "Yippee"