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 ก็ทำงานกับภาษาอื่นได้ง่าย ๆ เลย

Advertisements
This เรื่อง was posted in ไม่มีหมวดหมู่. Bookmark the permalink.

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s