Mozillian Meetup กรุงเทพ 15/7/60

วันเสาร์ที่ 15 กรกฎาคม พ.ศ. 2560 พบกันที่ BreadTalk ห้าง Gateway เอกมัยครับ

35935979345_a286ca02d2_o

คุยกันเรื่องการแปลคำยาก ๆ ต่าง ๆ รวมถึง web technology

35935971445_8f4b10f5d5_o

ใช้วิธีเปิดคำแปลมาดูกันใน tablet พร้อมกันเลยเครื่องเดียว ในนี้เปิด Pontoon บน Firefox Nightly บน Windows 10 บน Tablet ที่ใช้ CPU เป็น Atom X5 ถ้าจำไม่ผิด ก็ทำงานได้ราบรื่นดี

เราก็แปล string พวกที่ว่าไม่ค่อยจะตรงไปตรงมาเท่าไหร่

แล้วผสมไปกับคุยกันว่าถ้าเราจะเขียนโปรแกรมทำเว็บต่อไปในอนาคตจะใช้ภาษาอะไรดีมาเปรียบเทียบกัน

ติดตั้ง wordcutpy จาก pip ได้แล้วครับ

ติดตั้ง wordcutpy จาก pip ได้แล้วครับ


pip install wordcutpy

ง่าย ๆ แบบนี้เลย

ตอนใช้ก็ทำแบบนี้ครับ

#! -*- coding: UTF8 -*-
from wordcut import Wordcut
wordcut = Wordcut.bigthai()
print(wordcut.tokenize("กากา cat หมา"))

ขอบคุณคุณ Bird Praphan สำหรับ setup.py และทำ API ให้เรียกง่ายขึ้นด้วย bigthai ครับ

อ่านเพิ่ม: https://github.com/veer66/wordcutpy

เพิ

เล่าเรื่อง Database

เมื่อเช้าคิดว่าเดี๋ยวคนก็เลิกใช้เครื่องมือเก่า ๆ เอง ไม่มีใครคุยกับผมเรื่อง dBase III+ มาหลายปีแล้ว ผมก็ไม่เคยเชียร์ให้ใครเลิกใช้ dBase เลย

ค.ศ. 2013 ผมคิดว่าน่าจะลองสิ่งใหม่ ๆ บ้าง ก็เลยของใช้ MongoDB กับ Go ดู เพราะคิดว่าเวลา save album มันง่ายดี เพราะว่าผมใช้ JS เหมือนเลย เวลา save ก็ส่ง json ที่มี list ของรูปอยู่ใน album เลย แล้วใน Go ก็มาเขียนประมาณนี้

json.Unmarshal([]byte(raw_album), &album)
app.PhotoDb.C("album").UpdateId(album.Id, album)

ปลาย ๆ ค.ศ. 2014 ผมลองย้ายไปเป็น JS ดู แค่นี้เสร็จเลย แต่ผมตัดพวก error handling ออกนะครับเพราะ code เพราะ code หลัก 2-3 บรรทัดนี่ ไป handle error เสีย 8 บรรทัดได้ ที่เหลือหลัก ๆ ก็เป็นพวกที่เขียนไว้ประกาศ type แต่ว่าก็เปลี่ยนไปใช้ node.js ตั้งแต่ปลายปี 2014

มาปีนี้จะส่งเว็บนี้ไปให้มิตรสหายท่านอื่นไปปรับปรุงต่อ ก็ติดขัดเหมือนกัน เพราะ dev ส่วนมากที่ผมรู้จักไม่ได้ใช้ MongoDB มาก่อน อย่างไรก็ตามท่านก็มีความอยากเรียนรู้นะครับแต่ก็คงใช้เวลาเหมือนกัน

น่าจะพอสรุปได้ว่าผมเปลี่ยนมาใช้ MongoDB ไวไป อย่างน้อยก็สำหรับงานแนว ๆ อาสาสมัคร แต่ก็แบบที่ว่าไปตอนแรกวันหนึ่งอาจจะไม่มีคนคุยเรื่อง MySQL กับผมแล้วก็ได้ หรือไม่ผมก็อาจจะตายก่อนก็ได้

Go ไม่ยากมาก? Ruby ไม่ช้ามาก?

ผมอ่าน blog ที่คนเอา Gin ที่ใช้ภาษา Goblog ที่คนเอา Gin ที่ใช้ภาษา Go มาเขียน ก็พบว่าพอมี router มี H มาช่วยนี้ Go ดูเขียน REST (server) ง่ายไปเลย

แต่อีกฝังหนึ่งมาดู benchmark ผมดูแบบ single query นะครับ เพราะว่าส่วนมากงานก็ต่างจาก print Hello world ออกมาเฉย ๆ เยอะเหมือนกัน ก็พบว่าใช้ Roda ที่เขียน Ruby กับ Bottle.py ที่ใช้ภาษา Python รับ request ได้เยอะกว่า Gin อีก

ทำให้คิดว่าระหว่างพวก Go Python Ruby เอามา query DB แล้วพ่น JSON ออกไป เรื่องความเร็วช้า ความยากง่ายก็ไม่ได้ทิ้งกันสักกี่มากน้อย

ประเด็นที่ผมสนใจตอนนี้คืออะไรแก้เว็บแล้ว reload/restart ไวกว่า

rbre: อยากใช้ regexp split แบบ Ruby ใน Clojure

ผมเขียน clojure.string/split แล้วจะให้มัน captures ตัวที่เอามาเป็น delimiter ด้วยเช่น (\s+) แบบนี้ไม่ได้ ก็เลยเขียนใหม่เลย ซึ่งทำแบบนี้ได้


(re-split (make-re "(\\s+)") "a b c")
;; output: ["a" " " "b" " " "c"]

ชื่อโปรแกรม rbre ใช้งานจาก Clojar ได้เลย

rbre มันไปเรียกใช้ Joni ที่ JRuby port libonig ที่ MRI Ruby ใช้มาอีกที ก็น่าจะทำให้เขียนแล้วคล้าย ๆ Ruby

interop ระหว่าง programming language ต่าง ๆ

ในโครงการหนึ่งอาจจะมีโปรแกรมบางส่วนอยากให้เร็วบางส่วนอยากให้แก้ง่าย ๆ ทำให้หลาย ๆ ครั้งใช้ programming language หลาย ๆ ภาษาก็สะดวกดี แต่ว่าหลาย ๆ ภาษามันจะคุยกันได้ไง

ผมมองว่ามันมีการคุยกันข้ามภาษาอยู่ 2 แบบคือ (1) คุยข้าม process และ (2) คุยแบบใน process เดียวกัน

แบบที่ 1 คือ คุยข้าม process อันนี้ง่ายเพราะว่ามัน share memory กันไม่ได้อยู่แล้ว ต้องส่ง message เอา เราก็อาจจะเคยใช้อยู่แล้ว เช่น เวลาเขียน PHP ไปคุยกับ MySQL ก็คนละภาษาคนละ process กัน หรือว่าจะเรียกผ่าน HTTP ก็ได้เดี๋ยวนี้ก็เป็นที่นิยม อย่างไรก็ตามท่านี้มันมี overhead เยอะถ้าเรียกบ่อย ๆ โปรแกรมอาจจะช้าได้

แบบที่ 2 คือคุยใน process เดียวกัน เท่าที่ผมใช้บ่อย ๆ มี 3 แบบ ซึ่งไม่ใช่การแบ่งชนิดที่ดีหรือเป็นการทั่วไปแน่ ๆ คือ (1) share c library กับภาษาอื่น (2) แชร์โดยการเรียก function และ object ใน JVM หรืออาจจะ Mono ก็ได้? (3) แชร์กันระหว่างภาษาที่มี runtime ที่มี GC ของตัวเอง

  1. share c library กับภาษาอื่น: สำหรับคนที่เกิดหลัง unix ท่านี้มันก็ท่ามาตรฐานเลย ทุกอย่างมักจะเรียกจาก libc หรือแม้แต่ syscall ก็ใช้ C ภาษาต่าง ๆ เวลาทำ extension Ruby Python Lua Guile ก็มาเรียกผ่านท่านี้หมด เรื่องจัดการ memory มันไม่มีปัญหามากเพราะ C มันไม่จัดการให้อยู่แล้ว code ส่วนที่เป็น extension ก็ไป free เอาเองหรีอไปฝาก GC ของภาษาอื่น free ให้ อย่างไรก็ตามตอนใช้จริง ๆ เวลาไป deploy บน Windows Server lib ที่เขียนด้วย C ที่ว่าเคย install ง่าย ๆ บางทีมันก็ไม่ง่ายแล้ว
  2. ท่าที่สองคือเรียกกันไปมาระหว่างภาษาบน JVM: เห็นได้ว่า Kotlin Clojure JRuby ไปเรียก library ที่เขียนด้วย Java มาใช้ได้เนียน ๆ ราวกับว่าเขียนด้วยภาษาเดียวกัน ส่วนมากก็จะใช้สิ่งที่มีของ Java ร่วมกันไปเลย เช่น String ก็จะใช้ string ที่ encode ด้วย UTF-16 ของ Java ทำให้ share กันได้โดยไม่ต้องแปลงไปแปลงมา ส่วน GC ก็ให้ JVM จัดการไป อย่างไรก็ตามมี JVM เข้ามาเรื่อง start ช้าตัวใหญ่ กิน memory ก็เป็นประเด็นตามมาด้วย
  3. แชร์กันระหว่างภาษาที่มี runtime ที่มี GC ของตัวเอง: อย่างเช่น อยากจะเขียน code ให้ interop กันระหว่าง Ruby กับ Go หรือว่า Python กับ Go ส่วนไหนที่อยากจะให้ง่าย ๆ เปลี่ยนบ่อย ๆ ก็ไปใช้ Ruby ส่วนไหนที่อยากให้เร็วก็ไปใช้ Go ปัญหามันจะอยู่ที่ว่า Go ก็มี GC ส่วน Ruby ก็ดันมี GC เหมือนกัน พอส่ง pointer ของ Go มาให้ Ruby แล้ว GC ของ Go มันจะรู้ไหมว่าเมื่อไหร่จะ free ได้ เท่าที่ผมอ่านมาคร่าว ๆ คืออย่างแรกคืออย่าส่ง pointer ของ Go มาให้ Ruby ถ้าเป็น Go 1.6 ขึ้นไปมันไม่ยอมแล้ว ใน Go มี C.CString Unsafe.Pointer เท่าที่อ่านคร่าว ๆ มันไม่นับว่าเป็น Go pointer สามารถมาเรียก free ทีหลังเองได้

ป.ล. ความรู้เรื่องนี้ของผมไม่แน่นเลย ไม่แตกฉานเลย ก็อย่าได้เชื่อมากครับ ถ้ามีอะไรผิดพลาดโปรดชี้แนะด้วย

update 1: รูปแบบของการเรียกผ่านกันข้าม process ที่อาจจะง่ายที่สุดน่าจะเป็นการใช้ unix pipe เช่น

ruby sth.rb | grep '^A'

ทำนองนี้นะครับโปรแกรมที่เขียนด้วย Ruby ก็ทำงานกับภาษาอื่นได้ง่าย ๆ เลย

null/nil

จากที่อ่าน Wikipedia มาซึ่งที่ไปที่  InfoQ อีกที null pointer เริ่มใช้ครั้งแรกใน Algol W ที่สร้างขึ้นมาในค.ศ. 1966 ซึ่งผมก็ไม่เคยเขียน Algol เลย

nil ไม่ใช่การปรับปรุง null เพราะว่า nil ใน Lisp เกิดมาก่อนอีก อย่างน้อยใน ค.ศ. 1960 ตามเอกสารนี้ ก็บอกไว้ชัดเจนเลยว่า (m) คือรูปย่อของ (m . NIL) และ list[e1;e2;…;e_n] ก็คือ cons[e_1;cons[e2;…;cons[e_n;NIL]]] ส่วน null เป็น predicate ที่ว่า null[x] = atom[x] and eq[x;NIL]

ใน Ruby ก็มี nil เหมือนกัน แต่ไม่มี list ไม่มี cons มี Array แทนแล้วเวลาทำอะไรก็ออกแนว message passing แทนที่จะเป็น function แบบ Lisp มันก็ไม่มีอะไรมาแทน cons ด้วย จะใช้ << หรือ push แทนก็ไม่ได้ แบบข้างล่างนี้เจ๊งหมด แน่นอนว่า "A" และ nil มันไม่ใช่ Array

nil << "A"
"A" << nil
"A".push(nil)
nil.push("A")

แต่ถ้าเป็น Lisp ก็จะเขียนแบบด้านล่างได้เลย

(cons "A" nil) ;; ได้ ("A")

หรือถ้าเป็น Clojure ก็จะเขียนแบบข้างล่างได้ด้วย

(conj nil "A") ;; ได้ ("A")

อาจจะเป็นไปได้ว่า nil ใน Ruby เขียนว่า nil ก็จริงแต่คุณสมบัติเหมือน null ของ Algol W ทั้ง Go และ Pascal ก็น่าจะเข้ากรณีเดียวกันกับ Ruby

Matrix.org

Matrix เป็นระบบ chat แบบที่(ผม)ต้องการ

1. เป็น Federation มีหลาย server คนละเจ้าของได้
2. Optional end-to-end encryption
3. คุณกับคนที่ใช้ IRC อยู่เดิมได้
4. ใช้บน Android, iOS, GNU/Linux, Windows, macOS และ web ได้

อ่านเพิ่มได้จาก https://matrix.org/

แต่ถ้าอยากลองเล่นเข้า https://riot.im เลยครับ