Functional in Python

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

เคยเห็นใน Tutorial ว่า Python สามารถคิดและเขียนแบบ Functional ได้ด้วย แต่ว่าดูแล้วงงๆอะครับ(เคยเขียน C,C++ มาก่อนศึกษา Python) ไม่เข้าใจว่า มันมีการลำดับความคิดยังไงเหรอครับ ไอการเขียนแบบ Functional เนี๊ย

veer's picture

ผมไม่แน่ใจว่าจะตอบได้ดีกว่าที่วิกิพีเดียหรือเปล่า

sugree's picture

ผมก็รอฝึกจาก http://www.codenone.com/forum/8

ผมเห็นทำนองเดียวกับคุณ sugree นะครับ
คือ ลองอ่านเอาไอเดียสักหน่อย
แล้วก็โหลดพวก compiler ของภาษามาลง
แล้วก็ทำเลยล่ะครับ เดี๋ยวไว้คุณ pphetra มาแปะโจทย์ แล้วมาลองทำด้วยกันสิครับ

veer's picture

ผมทำโจทย์มาทำ caml ด้วยละกัน (ก่อนจะไปเล่นอะไรกะ xml ต่อ :-P)

bpitk's picture

ไม่รู้ผมเข้าใจถูกหรือเปล่า (ผิดก็ช่วยท้วงติงหน่อยนะครับ)
อ่านๆดู Functional Programming ก็คล้ายMathม.ปลาย เรื่องฟังก์ชัน แหละ
เช่น ฟังก์ชัน f(x) = ax+b (แล้วเราไปplotกราฟ)
แต่ Functional Programming กว้างไปกว่านั้น ไม่ใช่แค่plotกราฟ สั่งทำงานต่างๆด้วย
ก็เลยสามารถนำทฤษฎีคณิตศาสตร์มากมาย (สมัยก่อนมีPC) มาประยุกต์ใช้ได้ด้วย
และก็มีเทคนิคต่างๆอีกมากมายให้เลือกใช้ เช่น
-Functions are first class
-Loop,Recursion
-Bindings
-Closures ,etc.
คำสั่งสำหรับ Functional Programming in Python โดยตรงก็เช่น map ,filter ,reduce
อ่าน 3 tutorial นี้สิครับ ดีมากเลย (มีเหมือนกันอยู่ที่web ibm แต่เดี้ยงไปแล้ว)
http://gnosis.cx/publish/programming/charming_python_13.html
http://gnosis.cx/publish/programming/charming_python_16.html
http://gnosis.cx/publish/programming/charming_python_19.html

ปล.ขอเสนอว่า ใครคล่องหลายภาษา ช่วยแปลFunctional Programmingภาษาอื่น จากห้องโน้น มาเป็น Python ที่ห้องนี้บ้างสิครับ :)

sugree's picture

อ้างอิงจาก http://www.codenone.com/node/30

  1. ตัวแปร assign ได้ครั้งเดียว ห้ามแก้ไข (immutable)
  2. พวก list ก็เป็น immutable เหมือนกัน ดังนั้น ประโยคแบบนี้ a = []; a << 1 ไม่มีใช้ใน erlang
  3. ไม่มี global variable ให้ใช้

แปลว่า

def problem21_2(input,n):
    return [input[i:i+n] for i in range(0,len(input),n)]

problem21_3 = lambda input,n: [input[i:i+n] for i in range(0,len(input),n)]

def sep(input,n,i=0):
    if i >= len(input):
        return []
   else:
        return [input[i:i+n]] + sep(input,n,i+n)

ทั้งหมดนี่ก็นับว่าเป็น functional programming ทั้งหมด

เอ่อ… ผมแค่เดา

ผมว่า อันนั้นเป็นข้อจำกัดของ Erlang น่ะครับ

เท่าที่ผมเข้าใจ functional programming คือ การเขียนโปรแกรมโดยการนิยาม function

แปลว่าอะไร แปลว่าทุกอย่างเป็นการเรียกใช้ function ทั้งหมด โดยแก่นแท้แล้วภาษาไม่มีอย่างอื่นนอกจากการเรียก function ตัวภาษาไม่มีแนวคิดเกี่ยวกับลำดับการทำงาน แน่นอนว่าจะไม่มีลูป

นอกจากนี้ตัวแปรในภาษาเหล่านี้ไม่ได้หมายถึง "ตำแหน่ง" ที่เก็บข้อมูล แต่เป็นแค่สัญลักษณ์แทนค่าบางอย่าง (เหมือนในคณิตศาสตร์) อาจจะถูกกำหนดค่าใหม่ได้ แต่ไม่ได้หมายความว่าค่าเก่าเปลี่ยนไป หรืออะไรพวกนี้ มันอาจเป็นตัวแปรตัวใหม่ไปเลยก็ได้ ยกตัวอย่างเช่นใน ML

- val x = 10;        {กำหนดให้ x แทนค่า 10}
val x = 10 : int
-
- fun f(y) = y + x;          {เหมือนสั่งให้ f(y) = y+10}
val f = fn : int -> int
-
- f(10);
val it = 20 : int
-
- val x = 100;               {ให้ x แทน 100}
val x = 100 : int
-
- f(10);                     {f(y) = y + 10 ก็เหมือนเดิม}
val it = 20 : int

(ของที่ตาม "-" คือสิ่งที่เราพิมพ์เข้าไป คำสั่ง val คือคำสั่งกำหนดค่าให้ตัวแปร เช่น val x = 10; คือกำหนดให้ x แทนค่า 10 ส่วน val it = xxx:int เป็นค่าที่ ML ตอบกลับมา)

หรือถ้าจะพูดอีกแบบ ภาษาที่เป็น pure functional คือภาษาที่ไม่มี side effect เลย เพราะว่าไม่มีอะไรที่ทำให้เกิด side effect ได้ ทีนี้ภาษา functional ส่วนใหญ่ก็หลีกไม่พ้นต้องมี input/output ก็สุดแต่ภาษาจะจัดการครับ แถมบางภาษา เช่น ML, Lisp ยังมีคำสั่งที่มี side effect ให้ด้วย เช่นใน ML มี reference

sugree's picture

แปลว่าข้างบนนั้นมีแค่อันสุดท้ายที่เป็น functional ใช่มั๊ยครับ ไม่มีลูปก็ต้องหลบไป recursive หรือไม่ก็ใช้ map/filter/reduce ที่มีอยู่แล้ว (คงนับว่าเป็น functional)

น่าจะอย่างนั้นนะครับ แต่จริง ๆ ผมว่ามองได้หลายระดับ

ถ้าจะให้เห็นภาพนะครับ ก็คืออาจจะมองว่า เวลาเราพูดถึงฟังก์ชันเนี่ยะ มันจะเป็นการส่งค่า-รับค่า ทีนี้ ผมชอบมองฟังก์ชันเป็นกล่อง ๆ เช่น สมมติผมมีฟังก์ชัน fac (torial) แล้วเรียก fac(10)

     +-------+
10-->|n      |
     |  fac  |
     |       |
     +-------+

ทีนี้ เวลานิยามแบบ functional เนี่ยะ มันก็น่าจะนิยามได้โดยการเรียก function (ถ้ามองก็คือ เขียนเป็น circuit) เช่น fac(n):

    +---------------------------------------------+
    |        +----+                               |
--->|n--+--->|    |                +---------+    |
    |   |    | =? |--------------->| if-else |    |
    |   | 0->|    |                |         |    |
    |   |    +----+            1-->|         |--->|--->
    |   |                          |         |    |
    |   |    +-----+   +------+    |         |    |
    |   +--->| dec |-->|n     |--->|         |    |
    |        +-----+   |  fac |    +---------+    |
    |                  +------+                   |
    +---------------------------------------------+
sugree's picture

โอ้ นี่คือคำแนะนำที่ดีที่สุดสำหรับ functional ที่เคยเห็นในรอบ 10 ปี ขอบคุณมากครับ

ขอบคุณครับ ;)

ผมจำมาจากหนังสือสักเล่มนี่แหล่ะครับ
เดี๋ยวหาก่อน (คิดว่ามี on-line)

จากหนังสือ Common Lisp: A Gentle Introduction to Symbolic Computation ของ David S. Touretzky

มี on-line ที่นี่ นะครับ

sugree's picture

f = lambda input,n: map(lambda i: input[i:i+n],range(0,len(input),n))

แบบนี้พอใช้ได้มั๊ยครับ เอา map() มาแทน for

น่าจะได้แล้วนะครับ อิอิ

bpitk's picture

edit: ขอแก้ที่เข้าใจคลาดเคลื่อน

Functional Programming ไม่ใช้Loop เช่น ใช้ map แทน

veer's picture

ช่วงนี้ผมลองมาฝึกด้วย Scheme มี หนังสือ หรือ web อะไรที่ช่วยเรื่อง functional programming เยอะดี

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น