Lisp ไม่จำเป็นต้องเขียนแบบ Functional Programming

ใน code นี้ Python กับ Emacs Lisp แทบจะเหมือนกันทุกอย่างบรรทัดต่อบรรทัด เขียนแบบ imperlative ธรรมดา

อาจจะต่างบ้างที่ (cdr …) มี time complexity เป็น O(1) แต่ [1:] นี่ O(k) เพระา data structure ที่ใช้ต่างกัน ถึงจะบอกว่าเป็น list เหมือนกันก็ตามแต่ของ Emacs เป็น singly linked list ของ Python ผมเดา ๆ ว่าน่าจะเป็น array list?

 

emacs_py

 

อยากไรก็ตามใน Emacs Lisp ปกติเวลาทำแบบนี้ก็จะใช้ (dolist …) แทน และใน Python ก็ใช้ for กับ iterator อันนี้เพียงแต่อยากยกตัวอย่างให้ดูว่ามันก็ไม่ได้ต่างกันมาก

Advertisements

XPCOM

เปิดดู XPCOM หลังจากที่ไม่ได้ดูมาหลายปี เพราะว่าอยากรู้ว่า blog ที่อ่านเมื่อเช้าจะจริงหรือเปล่า
 
มันก็ใช่คือ XPCOM นี่ประมาณว่าไปล้วงเอา class ของ C++ ใน Gecko ออกมาใช้ได้เลย เฉพาะ class ที่ทำเป็น XPCOM ไว้
 
ท่าแบบนี้จะไปปรับ class ใน Gecko เองก็น่าจะทำให้ addon พังได้เลย?
 
แล้วก็ดูจาก Wikipedia ก็มีกรณี่ใช้ XPCOM เยอะจน Apple ไปเลือก KHTML และปี 2008 ลดการใช้ XPCOM ลง Gecko ก็ไวขึ้น
 
แต่คงลืมไม่ได้ว่า Firefox สร้างชื่อขึ้นมาได้ก็เพราะ Addon ที่ขี่ XPCOM อยู่นี่ล่ะ
 
 

ร้านกาแฟใหม่ที่เกษตรฯ: The Black Bear Brews

หลังจากที่ First Espresso หายไปก็มีร้านชามาแทน ตอนนี้ร้านชาก็ไปแล้ว เปลี่ยนเป็นร้านกาแฟ The Black Bear Brews แทน

P1060299

ดูราคาแล้วก็รู้สึกว่าท่าจะไม่ธรรมดาเพราะว่ากาแฟร้านแพงกว่าเย็น ปกติผมเจอแต่กาแฟเย็นแพงกว่า
P1060296

 

ก็เลยลอง cappuccino ร้อนดู ลุงบาริสต้าชงมาดีมากสำหรับราคานี้ แน่นอนว่าเมล็ดที่ใช้ก็ดีด้วย
P1060288

 

สรุปว่าดี พากันไปดื่มเลย

 

[video] วิธีตรวจ/แก้งานแปล mozilla.org

 

วันที่ 14 พ.ย. 2560 นี้ Firefox 57 จะออกแล้ว มีการปรับปรุงเยอะมาก ๆ น่าจะพอหรือยิ่งกว่าสมัย Firefox 3.X เลย

คำอธิบาย/โฆษณาอะไรต่าง ๆ อยู่เว็บ Mozilla.org ซึ่งต้องขอขอบคุณทุกท่านที่ช่วยกันแปลเป็นภาษาไทยจนเสร็จแล้ว

ข้อดีของการแปลเสร็จไป 1 รอบการตรวจทาน ก็จะอ่านจากเว็บที่เหมือนจริงได้เลย ซึ่งก็น่าจะง่ายและเห็นภาพขึ้น

ผมก็เลยทำวิดีโอแสดงวิธีตรวจ/แก้งานแปล mozilla.org คร่าว ๆ ขึ้นมาครับ เริ่มจากเข้า https://pontoon.mozilla.org ครับ

Typeclass เทียบกับ Java

พอดู typeclass กับ parametric polymorphism ใน Haskell แล้วก็คิดว่า มันก็คล้าย ๆ Generic Methods and Bounded Type Parameters ใน Java หรือเปล่า
 
 
public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
 
 
ตรง extends Comparable<T> ก็คล้าย ๆ เอา typeclass มาใส่เป็น constraint
 
แต่ประมาณว่าถ้ามันพลังเท่า ๆ กันก็น่าจะ define monad แบบใน Haskell ด้วย Java ได้ ก็เลยไปหาดูเจอ https://stackoverflow.com/questions/35951818/why-can-the-monad-interface-not-be-declared-in-java ก็พบว่าไม่ได้ ส่วนที่พอจะจับใจความได้คือ:
no ability to specify that static members are part of the interface contract
สรุปว่าก็เกือบ ๆ จะพลังเท่ากัน แต่ไม่

GC ของ JVM จาก Redhat ที่แก้ปัญหา pause นาน

มิตรสหายหลายท่านเล่าให้ฟังว่า Java มันไม่ได้มีแค่ปัญหากิน RAM แต่ว่ามีปัญหาว่า GC มันพา pause นานด้วย ตอนที่ pause นี่ก็ทำงานไม่ได้ไปเลย

ท่าแก้แบบกำปั้นทุบดินสุด ๆ ก็คือทำ GC ใหม่

ใน Table 3 ผมเข้าใจว่าเขาลองกับ ElasticSearch

Max Pause ของ Parallel (GC) 3.04s แต่งานนี้ลดลงมาได้เหลือ 89.79ms ส่วนค่าเฉลี่ยก็ลดจาก 823.75ms มาเหลือ 53.01 ms

ที่น่าสังเกตคือเป็นงาน Redhat ที่ทำบน OpenJDK ไม่ใช่ของ Oracle ทำให้คิดว่าช่วงนี้อาจจะเป็นจุดเปลี่ยนสำคัญของ Java เหมือนกัน

https://dl.acm.org/citation.cfm?id=2972210

docx กับ odt

ไฟล์เอกสารยุคนี้ทั้ง docx และ odt ข้างในเป็น XML ที่เอามา zip ไว้ ผมอยากจะเปิดไฟล์มีดูว่ามีส่วนไหนที่ถูกขีดเส้นใต้บ้าง โดยที่ใช้ XML parser เท่านั้นเองจะทำอย่างไร

ผมเลยลองสร้างเอกสารขึ้นมาหน้าตาแบบข้างล่าง:

animal_libre

ซึ่งขีดเส้นใต้คำว่า “Dog” ไว้

พอแตก .docx ออกมาเข้างในจะมี word/document.xml

ข้างล่างผมดึงมาเฉพาะส่วนที่หุ้ม “Dog” อยู่

docx_u

ความประทับใจเกี่ยวกับ .docx คือ ตัวย่อเยอะมาก เช่น rPr ilvl คือคิตตี้อะไร แต่จริงๆ สามารถเปิดดูจากมาตรฐาน ISO 29500 ได้ แต่โดยสรุปแล้วส่วนที่ขีดเส้นใต้ก็คือ w:u แต่ไม่ได้หุ้ม Dog อยู่แต่ไปอยู่ใน node w:rPr ข้าง ๆ อีกที

ต่อไปเป็น .odt พอแตกออกมา ไฟล์หลักก็คือ content.xml:
odt_xml.png

ส่วนที่หุ้ม Dog อยู่ก็คือส่วนที่ highlight สีเหลือง ๆ ไว้จะเห็นว่า ชื่อ tag ชื่อ attribute เขียนมาเต็ม ๆ แทบจะไม่มีอะไรให้เดา แต่ว่าส่วนที่บอกที่ขีดเส้นใต้ไปอยู่ใน style P2 อีกที ซึ่งก็อยู่ในไฟล์เดียวกัน

odt_underline

อันนี้ชื่อก็บอกชัดเจน style:text-underline-style=”solid” บอกว่าขีดเส้นใต้เป็นเส้นทึบ

เวลาเขียนโปรแกรมสำหรับ odt ก็ประมาณข้างล่างนี้ครับ


require 'pp'
require 'zip'
require 'rexml/document'

def get_attrs(style_node)
  style_node.get_elements('.//style:text-properties')
    .map{|text_prop_node| text_prop_node["style:text-underline-style"] == "solid" \
         ? :underline : nil}
    .flatten
    .reject(&:nil?)
end

Zip::File.open('animal.odt') do |zipfile|
  content_xml = zipfile.select{|entry| entry.name == "content.xml"}[0]
                  .get_input_stream
                  .read
  doc = REXML::Document.new(content_xml)
  style_map = Hash[doc.root
                     .get_elements('//style:style')
                     .map{|node| [node['style:name'], get_attrs(node)]}]
  PP.pp doc.root
          .get_elements('//text:p')
          .map{|node| {text: node.text,
                       style: style_map[node['text:style-name']]}}
end

ใช้ rubyzip แตกไฟล์ content.xml ออกมาแล้ว แล้วก็หาว่า style ไหนขีดเส้นใต้บ้างแล้วใส่ไว้ใน style_map เสร็จแล้วก็มาไล่ดู text:p ทีละอัน

ผลตอนรันก็จะออกมาทำนองนี้


[{:text=>"Animal", :style=>nil},
{:text=>"Cat", :style=>[]},
{:text=>"Rat", :style=>[]},
{:text=>"Dog", :style=>[:underline]},
{:text=>"Elephant", :style=>[]},
{:text=>"Bird", :style=>[]}]

ส่วน docx ก็น่าจะอ่านได้คล้าย ๆ กัน

เพระาว่า .odt และ .docx เป็น xml ที่เอาไป zip ไว้ แค่ lib สำหรับ parse xml และหาด้วย xpath กับ lib ไว้แตก zip ใช้งาน odt กับ docx ได้แล้ว บางทีอาจจะง่ายกว่าใช้ lib สำหรับอ่านไฟล์เอกสารโดยเฉพาะอีกก็ได้

น้ำท่วมกับทวิตเตอร์

ผมเข้าไปหาทวีตด้วยคำว่า “น้ำท่วม” แทบทุกวัน สังเกตว่าพอน้ำท่วมอยุธยาก็เจอบ้างนิด ๆ หน่อย ๆ พอท่วมปทุมธานีก็จะเจอทวีตเยอะขึ้น ท่วมนนทบุรีก็เจอเยอะขึ้นกว่าปทุมธานีนิดหน่อย แต่พอท่วมกรุงเทพก็เจอเยอะชนิดที่ว่าทวีตท่วมจอแทน ส่วนขอนแก่น เชียงใหม่ ก็ทวีตเยอะพอ ๆ กับนนทบุรี

สรุปว่าคนอยุธยาไม่ค่อยใช้ทวิตเตอร์ ?