ผลต่างระหว่างรุ่นของ "Racket"
Jittat (คุย | มีส่วนร่วม) |
|||
(ไม่แสดง 24 รุ่นระหว่างกลางโดยผู้ใช้ 2 คน) | |||
แถว 1: | แถว 1: | ||
== ภาษา == | == ภาษา == | ||
Racket เป็นลูกหลานหนึ่งของภาษา LISP อ่านรายละเอียดเพิ่มเติมได้ที่ [http://theory.cpe.ku.ac.th/wiki/images/01204435-lect02-scheme.pdf เอกสาร scheme] | Racket เป็นลูกหลานหนึ่งของภาษา LISP อ่านรายละเอียดเพิ่มเติมได้ที่ [http://theory.cpe.ku.ac.th/wiki/images/01204435-lect02-scheme.pdf เอกสาร scheme] | ||
+ | |||
+ | Racket มี IDE ชื่อ DrRacket สามารถดาว์นโหลดได้ที่[http://racket-lang.org/ เว็บไซต์ของ Racket] | ||
=== REPL === | === REPL === | ||
แถว 30: | แถว 32: | ||
=== define === | === define === | ||
+ | ตัวอย่าง | ||
+ | |||
+ | (define (inc x) | ||
+ | (+ x 1)) | ||
+ | (define (dec x) | ||
+ | (- x 1)) | ||
+ | (define (square x) | ||
+ | (* x x)) | ||
+ | |||
+ | === if === | ||
+ | |||
+ | (define (myadd a b) | ||
+ | (if (= b 0) | ||
+ | a | ||
+ | (myadd (inc a) (dec b)))) | ||
+ | |||
+ | === list === | ||
+ | ; การใช้ quote (') | ||
+ | ถ้าใช้เครื่องหมาย single quote (') นำหน้า Racket จะไม่ evaluate วงเล็บนั้น แต่จะสร้าง list แทน | ||
+ | <pre> | ||
+ | > (1 2 3 4) | ||
+ | . . application: not a procedure; | ||
+ | expected a procedure that can be applied to arguments | ||
+ | given: 1 | ||
+ | arguments...: | ||
+ | 2 | ||
+ | 3 | ||
+ | 4 | ||
+ | > '(1 2 3 4) | ||
+ | '(1 2 3 4) | ||
+ | </pre> | ||
+ | |||
+ | ; การใช้ procedure list | ||
+ | โปรดอ่าน[[#procedure เกี่ยวกับ list|procedure เกี่ยวกับ list]] | ||
+ | |||
+ | ==== โครงสร้างของ list ==== | ||
+ | อันที่จริงแล้ว list มีนิยามว่า | ||
+ | # อาจจะเป็น list ว่าง (<tt>null</tt>) | ||
+ | # อาจจะเป็น pair (ใน racket เรียกว่า <tt>cons</tt> มาจาก '''cons'''truct) ของ ''ข้อมูล'' กับ ''list'' | ||
+ | |||
+ | ข้างล่างนี้คือตัวอย่างของโครงสร้างของ list | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! โครงสร้างเต็ม !! รูปแบบโดยใช้ quote | ||
+ | |- | ||
+ | | null || '() | ||
+ | |- | ||
+ | | (cons 1 null) || '(1) | ||
+ | |- | ||
+ | | (cons "a" (cons "b" (cons "c" (cons "z" (cons "" null))))) || '("a" "b" "c" "z" "") | ||
+ | |} | ||
+ | |||
+ | ==== procedure เกี่ยวกับ list ==== | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! ชื่อ procedure !! คำอธิบาย !! ตัวอย่าง | ||
+ | |- | ||
+ | | list | ||
+ | | สร้าง list -- มีความแตกต่างกับการใช้ quote สร้าง list เล็กน้อย แต่โดยทั่วไปแล้วจะเหมือนกัน ใช้แทนกันได้ | ||
+ | | | ||
+ | > (list 1 2 3) | ||
+ | '(1 2 3) | ||
+ | > (list) | ||
+ | '() | ||
+ | |- | ||
+ | | null / empty | ||
+ | | สร้าง '() ทั้งสอง procedure นี้เหมือนกันทุกประการ ใช้แทนกันได้ | ||
+ | | | ||
+ | > null | ||
+ | '() | ||
+ | > empty | ||
+ | '() | ||
+ | |- | ||
+ | | cons | ||
+ | | สร้าง pair | ||
+ | | | ||
+ | > (cons 1 null) | ||
+ | '(1) | ||
+ | > (cons 1 '(1 2 3 4)) | ||
+ | '(1 1 2 3 4) | ||
+ | |- | ||
+ | | list? | ||
+ | | ทดสอบว่าเป็น list หรือไม่ | ||
+ | | | ||
+ | > (list? null) | ||
+ | #t | ||
+ | > (list? '(1 2 3)) | ||
+ | #t | ||
+ | |- | ||
+ | | null? / empty? | ||
+ | | ทดสอบว่าเป็น '() หรือไม่ | ||
+ | | | ||
+ | > (null? null) | ||
+ | #t | ||
+ | > (null? '(1 2 3)) | ||
+ | #f | ||
+ | |- | ||
+ | | cons? | ||
+ | | ทดสอบว่าเป็น cons -- กล่าวคือ list ที่ไม่ใช่ '() -- หรือไม่ | ||
+ | | | ||
+ | (cons? '()) | ||
+ | > #f | ||
+ | (cons? '(1)) | ||
+ | > #t | ||
+ | |- | ||
+ | | first | ||
+ | | ดึงข้อมูล (ตัวแรก) | ||
+ | | | ||
+ | > (first '(1 2 3)) | ||
+ | 1 | ||
+ | > (first '()) | ||
+ | first: contract violation | ||
+ | expected: (and/c list? (not/c empty?)) | ||
+ | given: '() | ||
+ | |- | ||
+ | | rest | ||
+ | | ดึง list ของข้อมูลทั้งหมดนอกจากข้อมูลตัวแรก | ||
+ | | | ||
+ | > (rest '(1 2 3)) | ||
+ | '(2 3) | ||
+ | > (rest '(1)) | ||
+ | '() | ||
+ | > (rest '()) | ||
+ | rest: contract violation | ||
+ | expected: (and/c list? (not/c empty?)) | ||
+ | given: '() | ||
+ | |} | ||
+ | |||
+ | procedure ทั้งหมดในตารางใช้เวลา <math>O(1)</math> | ||
+ | |||
+ | * สังเกตว่าที่ racket สามารถหา rest ได้อย่างรวดเร็ว เนื่องจากโครงสร้างของ list ที่จริงแล้วคือ cons ซ้อนกัน การหา rest อันที่จริงแล้วจึงเป็นเพียงแค่การหาข้อมูลตัวหลังของ cons ตัวนอกสุด | ||
+ | |||
+ | ==== การดำเนินการกับ list ==== | ||
+ | <pre> | ||
+ | (define (mylen lst) | ||
+ | (if (null? lst) | ||
+ | 0 | ||
+ | (+ 1 | ||
+ | (mylen (rest lst))))) | ||
+ | |||
+ | > (mylen '("a" "b" "c" "d")) | ||
+ | 4 | ||
+ | </pre> | ||
+ | |||
=== lambda === | === lambda === | ||
− | === | + | |
+ | === local variables: let, let* === | ||
+ | |||
+ | (define (f x) | ||
+ | (let ([x1 (+ x 1)] | ||
+ | [x2 (+ x 2)]) | ||
+ | (+ x1 x2))) | ||
+ | |||
+ | === Useful functions === | ||
+ | |||
+ | * equal? | ||
+ | <pre> | ||
+ | > (equal? '() empty) | ||
+ | #t | ||
== แบบฝึกหัด 1 == | == แบบฝึกหัด 1 == | ||
+ | 1. mysum | ||
+ | <pre> | ||
+ | > (mysum '(1 2 3)) | ||
+ | 6 | ||
+ | </pre> | ||
+ | |||
+ | 2. mymax | ||
+ | <pre> | ||
+ | > (mymax '(1 2 3 -1)) | ||
+ | 3 | ||
+ | </pre> | ||
+ | |||
+ | 3. myappend | ||
+ | <pre> | ||
+ | > (myappend '(1 2 3 4) 100) | ||
+ | '(1 2 3 4 100) | ||
+ | </pre> | ||
+ | |||
+ | 4. myreverse | ||
+ | <pre> | ||
+ | > (myreverse '(1 2 3 4)) | ||
+ | '(4 3 2 1) | ||
+ | </pre> | ||
+ | |||
+ | 5. myconcat | ||
+ | <pre> | ||
+ | > (myconcat '(1 2 3 4) '(10 20 30)) | ||
+ | '(1 2 3 4 10 20 30) | ||
+ | </pre> | ||
+ | |||
+ | 6. myslice | ||
+ | <pre> | ||
+ | > (myslice '(1 2 3 4 5 6 7) 3 6) | ||
+ | '(4 5 6) | ||
+ | </pre> | ||
+ | |||
+ | 7. myrange | ||
+ | <pre> | ||
+ | > (myrange 5 10) | ||
+ | '(5 6 7 8 9) | ||
+ | </pre> | ||
+ | |||
+ | 8. mycascade | ||
+ | |||
+ | > (mycascade '(1 2 3 4 5 6)) | ||
+ | '(1 (2 (3 (4 (5 (6)))))) | ||
+ | |||
+ | 9. myflatten | ||
+ | <pre> | ||
+ | > (myflatten '(1 (2 3) 4 (5 (6 7)))) | ||
+ | '(1 2 3 4 5 6 7) | ||
+ | </pre> | ||
+ | |||
+ | == Tail recursion == | ||
+ | <pre> | ||
+ | (define (fact1 n x) | ||
+ | (if (= n 0) | ||
+ | x | ||
+ | (fact1 (- n 1) | ||
+ | (* n x)))) | ||
+ | |||
+ | (define (fact n) | ||
+ | (fact1 n 1)) | ||
+ | </pre> | ||
+ | |||
+ | == Binary search tree == | ||
+ | Representing BST | ||
+ | <pre> | ||
+ | (define T '(5 | ||
+ | (3 () (4 () ())) | ||
+ | (12 (7 () (9 () ())) | ||
+ | (15 () ())))) | ||
+ | </pre> | ||
+ | |||
+ | Accessing value, left child, and right child | ||
+ | <pre> | ||
+ | > (car T) | ||
+ | 5 | ||
+ | > (first (rest T)) | ||
+ | '(3 () (4 () ())) | ||
+ | > (cadr T) | ||
+ | '(3 () (4 () ())) | ||
+ | > (caddr T) | ||
+ | '(12 (7 () (9 () ())) (15 () ())) | ||
+ | </pre> | ||
+ | |||
+ | Seaching (using if) | ||
+ | <pre> | ||
+ | (define (contains? node val) | ||
+ | (if (null? node) | ||
+ | #f | ||
+ | (let ([nv (car node)] | ||
+ | [lchild (cadr node)] | ||
+ | [rchild (caddr node)]) | ||
+ | (if (= val nv) | ||
+ | #t | ||
+ | (if (< val nv) | ||
+ | (contains? lchild val) | ||
+ | (contains? rchild val)))))) | ||
+ | </pre> | ||
+ | |||
+ | Searching (using cond) | ||
+ | <pre> | ||
+ | (define (contains? node val) | ||
+ | (if (null? node) | ||
+ | #f | ||
+ | (let ([nv (car node)] | ||
+ | [lchild (cadr node)] | ||
+ | [rchild (caddr node)]) | ||
+ | (cond [(= val nv) #t] | ||
+ | [(< val nv) (contains? lchild val)] | ||
+ | [else (contains? rchild val)])))) | ||
+ | </pre> | ||
== ท่าพื้นฐาน == | == ท่าพื้นฐาน == | ||
=== functional programming === | === functional programming === | ||
=== filter, map, fold === | === filter, map, fold === | ||
+ | |||
+ | === Examples === | ||
+ | ==== Quicksort ==== | ||
+ | <pre> | ||
+ | (define (qsort lst) | ||
+ | (cond | ||
+ | [(empty? lst) empty] | ||
+ | [(cons? lst) | ||
+ | (let ([pivot (first lst)] | ||
+ | [r (rest lst)]) | ||
+ | (append (qsort (filter (lambda (e) (< e pivot)) r)) | ||
+ | (append (list pivot) | ||
+ | (qsort (filter (lambda (e) (>= e pivot)) r)))))])) | ||
+ | </pre> | ||
== แบบฝึกหัด 2 == | == แบบฝึกหัด 2 == |
รุ่นแก้ไขปัจจุบันเมื่อ 23:47, 30 ตุลาคม 2557
ภาษา
Racket เป็นลูกหลานหนึ่งของภาษา LISP อ่านรายละเอียดเพิ่มเติมได้ที่ เอกสาร scheme
Racket มี IDE ชื่อ DrRacket สามารถดาว์นโหลดได้ที่เว็บไซต์ของ Racket
REPL
ส่วนล่างของจอ จะเป็น read-eval-print-loop คือพิมพ์ expression เข้าไป ระบบจะอ่าน คำนวณแล้วก็พิมพ์คำตอบ เช่น
> 5 5 > (+ 10 5) 15 > "hello" "hello" > (substring "hello" 1 3) "el" > (+ (* 4 5) 2) 22
ไวยากรณ์พื้นฐานของภาษา Racket คือการเรียกฟังก์ชัน:
(ฟังก์ชัน อาร์กิวเมนท์1 อาร์กิวเมนท์2 ...)
เราจะไม่สามารถเขียนวงเล็บเล่น ๆ ได้เลย เช่น ถ้าสั่ง (5) จะได้ error ดังนี้
> (5) . . application: not a procedure; expected a procedure that can be applied to arguments given: 5 arguments...: [none]
define
ตัวอย่าง
(define (inc x) (+ x 1)) (define (dec x) (- x 1)) (define (square x) (* x x))
if
(define (myadd a b) (if (= b 0) a (myadd (inc a) (dec b))))
list
- การใช้ quote (')
ถ้าใช้เครื่องหมาย single quote (') นำหน้า Racket จะไม่ evaluate วงเล็บนั้น แต่จะสร้าง list แทน
> (1 2 3 4) . . application: not a procedure; expected a procedure that can be applied to arguments given: 1 arguments...: 2 3 4 > '(1 2 3 4) '(1 2 3 4)
- การใช้ procedure list
โปรดอ่านprocedure เกี่ยวกับ list
โครงสร้างของ list
อันที่จริงแล้ว list มีนิยามว่า
- อาจจะเป็น list ว่าง (null)
- อาจจะเป็น pair (ใน racket เรียกว่า cons มาจาก construct) ของ ข้อมูล กับ list
ข้างล่างนี้คือตัวอย่างของโครงสร้างของ list
โครงสร้างเต็ม | รูปแบบโดยใช้ quote |
---|---|
null | '() |
(cons 1 null) | '(1) |
(cons "a" (cons "b" (cons "c" (cons "z" (cons "" null))))) | '("a" "b" "c" "z" "") |
procedure เกี่ยวกับ list
ชื่อ procedure | คำอธิบาย | ตัวอย่าง |
---|---|---|
list | สร้าง list -- มีความแตกต่างกับการใช้ quote สร้าง list เล็กน้อย แต่โดยทั่วไปแล้วจะเหมือนกัน ใช้แทนกันได้ |
> (list 1 2 3) '(1 2 3) > (list) '() |
null / empty | สร้าง '() ทั้งสอง procedure นี้เหมือนกันทุกประการ ใช้แทนกันได้ |
> null '() > empty '() |
cons | สร้าง pair |
> (cons 1 null) '(1) > (cons 1 '(1 2 3 4)) '(1 1 2 3 4) |
list? | ทดสอบว่าเป็น list หรือไม่ |
> (list? null) #t > (list? '(1 2 3)) #t |
null? / empty? | ทดสอบว่าเป็น '() หรือไม่ |
> (null? null) #t > (null? '(1 2 3)) #f |
cons? | ทดสอบว่าเป็น cons -- กล่าวคือ list ที่ไม่ใช่ '() -- หรือไม่ |
(cons? '()) > #f (cons? '(1)) > #t |
first | ดึงข้อมูล (ตัวแรก) |
> (first '(1 2 3)) 1 > (first '()) first: contract violation expected: (and/c list? (not/c empty?)) given: '() |
rest | ดึง list ของข้อมูลทั้งหมดนอกจากข้อมูลตัวแรก |
> (rest '(1 2 3)) '(2 3) > (rest '(1)) '() > (rest '()) rest: contract violation expected: (and/c list? (not/c empty?)) given: '() |
procedure ทั้งหมดในตารางใช้เวลา
- สังเกตว่าที่ racket สามารถหา rest ได้อย่างรวดเร็ว เนื่องจากโครงสร้างของ list ที่จริงแล้วคือ cons ซ้อนกัน การหา rest อันที่จริงแล้วจึงเป็นเพียงแค่การหาข้อมูลตัวหลังของ cons ตัวนอกสุด
การดำเนินการกับ list
(define (mylen lst) (if (null? lst) 0 (+ 1 (mylen (rest lst))))) > (mylen '("a" "b" "c" "d")) 4
lambda
local variables: let, let*
(define (f x) (let ([x1 (+ x 1)] [x2 (+ x 2)]) (+ x1 x2)))
Useful functions
- equal?
> (equal? '() empty) #t == แบบฝึกหัด 1 == 1. mysum <pre> > (mysum '(1 2 3)) 6
2. mymax
> (mymax '(1 2 3 -1)) 3
3. myappend
> (myappend '(1 2 3 4) 100) '(1 2 3 4 100)
4. myreverse
> (myreverse '(1 2 3 4)) '(4 3 2 1)
5. myconcat
> (myconcat '(1 2 3 4) '(10 20 30)) '(1 2 3 4 10 20 30)
6. myslice
> (myslice '(1 2 3 4 5 6 7) 3 6) '(4 5 6)
7. myrange
> (myrange 5 10) '(5 6 7 8 9)
8. mycascade
> (mycascade '(1 2 3 4 5 6)) '(1 (2 (3 (4 (5 (6))))))
9. myflatten
> (myflatten '(1 (2 3) 4 (5 (6 7)))) '(1 2 3 4 5 6 7)
Tail recursion
(define (fact1 n x) (if (= n 0) x (fact1 (- n 1) (* n x)))) (define (fact n) (fact1 n 1))
Binary search tree
Representing BST
(define T '(5 (3 () (4 () ())) (12 (7 () (9 () ())) (15 () ()))))
Accessing value, left child, and right child
> (car T) 5 > (first (rest T)) '(3 () (4 () ())) > (cadr T) '(3 () (4 () ())) > (caddr T) '(12 (7 () (9 () ())) (15 () ()))
Seaching (using if)
(define (contains? node val) (if (null? node) #f (let ([nv (car node)] [lchild (cadr node)] [rchild (caddr node)]) (if (= val nv) #t (if (< val nv) (contains? lchild val) (contains? rchild val))))))
Searching (using cond)
(define (contains? node val) (if (null? node) #f (let ([nv (car node)] [lchild (cadr node)] [rchild (caddr node)]) (cond [(= val nv) #t] [(< val nv) (contains? lchild val)] [else (contains? rchild val)]))))
ท่าพื้นฐาน
functional programming
filter, map, fold
Examples
Quicksort
(define (qsort lst) (cond [(empty? lst) empty] [(cons? lst) (let ([pivot (first lst)] [r (rest lst)]) (append (qsort (filter (lambda (e) (< e pivot)) r)) (append (list pivot) (qsort (filter (lambda (e) (>= e pivot)) r)))))]))