WebAssembly เมื่อการพัฒนาเว็บเข้าสู่อีกโลกนึง

ในยุคที่มองไปทางไหนก็มีแต่การพัฒนา Software ด้วย Web Technology ไปหมดทุกทางและยิ่งเป็น Modern Web ที่มี JavaScript เป็นหัวใจสำคัญแล้วนั้น หลายๆปัญหาทางด้าน Performance ก็จะไปติดคอขวดอยู่ที่ Layer ของ JavaScript Engine ดังนั้นทางออกหนึ่งที่ทาง Community นั้นได้มองเห็นก็คือการต่อตรงกับ OS ไปเลยแทนที่จะต้องผ่านการแปล JavaScript ซึ่งนี่ก็คือหนึ่งในที่มาของ WebAssembly

WebAssembly คือการนำ Low Level Code ที่เขียนด้วย C/C++ (และอาจจะมีภาษาอื่นๆในอนาคตเพราะตอนนี้ก็มีภาษา Rust ที่ใช้ได้ด้วยเหมือนกัน) มาทำการรันภายใต้ Web Browser เพื่อให้ได้ Performance  สูงที่สุดรวมทั้งยังสามารถติดต่อกับ JavaScript ได้ด้วย ซึ่งหมายความว่ามันไม่ได้เป็นภาษาใหม่ที่จะมาแทน JavaScript แต่มันคือสิ่งที่จะช่วยยกระดับการพัฒนาเวปมากกว่าครับ และที่สำคัญโปรเจคนี้พัฒนาด้วยเจ้าใหญ่แห่งวงการทั้งนั้น เช่น Mozilla Microsoft Google Apple

เนื่องจากว่า WebAssembly นั้นค่อนข้าง Low Level มาก(แค่มีคำว่า Assembly ก็แลดูน่ากลัวแล้ว) ดังนั้นนักพัฒนาที่สนใจในเรื่องนี้ก็จำเป็นต้องรู้จักสิ่งเหล่านี้ก่อนครับ

  • Source Code แน่นอนว่าคือไฟล์ที่พวกเราเขียน Code ลงไปโดยจะแบ่งเป็น 2 ส่วนคือฝั่ง C/C++ กับฝั่ง JavaScript ครับ
  • Compiler เป็นตัวแปลงภาษา C/C++ ไปเป็น Bytes Code หรือ Machine Code ซึ่งภาษาที่ต้องใช้ Compiler นั้นจะเป็นภาษาที่มี Performance สูงกว่าภาษาพวก Script เพราะไม่ต้องแปลง Code ตอน เวลา Runtime
  • Bytes Code เป็นภาษาระดับกลางที่ทาง WebAssembly Runtime นั้นเข้าใจและทำงานติดต่อกับ OS ตรงๆ
  • Interoperability เป็นการทำงานเชื่อมกันระหว่างระบบหนึ่งกับอีกระบบหนึ่งเช่น การเรียกให้ Module ที่เขียนด้วย C++ ทำงานด้วย Code ของภาษา JavaScript หรือด้านสลับกัน

หลักการพัฒนาเว็บด้วย WebAssembly ก็คือ

  1. Developer เขียนโปรแกรมด้วย C/C++
  2. Developer ทำการ Compile C/C++ ที่เขียนไว้ให้เป็น WebAssembly Bytes Code (ไฟล์ .wasm) เพื่อให้พร้อมที่จะรันได้ใน Browser
  3. Developer ต้องเขียน JavaScript ให้ทำการโหลด .wasm ไฟล์มาไว้ใน Memory เพื่อให้ WebAssembly Runtime ที่อยู่บน Browser นั้นทำการแปลง Bytes Code ให้เป็น JavaScript Object
  4. Developer เรียกใช้งาน function ที่เขียนด้วย C/C++ ผ่าน JavaScript

ทีนี้เรามาลองดูแบบ Step by Step กัน

ก่อนอื่นเลยผมมี Code ที่เขียนด้วย C ง่ายๆคือ function การบวกเลข ช่ือไฟล์ demo.c

Screen Shot 2560-03-05 at 7.04.29 PM.png

สิ่งที่ต้องทำขั้นต่อไปคือ Compile Code ชุดนี้ให้เป็น .wasm ซึ่งเครื่องมือที่ใช้ค่อนข้างซับซ้อนสำหรับมือใหม่(อย่างผม) ซึ่งใช้ emcc (Emscriptenซึ่งเป็น Open Source โปรเจคซึ่งติดตั้งจาก ที่นี่

$emcc demo.c -Os -s WASM=1 -s SIDE_MODULE=1 -o democ.wasm

ด้วย command ข้างบนนี้เราก็จะได้ democ.wasm ซึ่งเป็นไฟล์ Bytes Code ที่ใช้งานได้กับ Browser ที่สนับสนุนแล้ว เช่น Google Chrome 57+ ขึ้นไป

หน้าตาของไฟล์ .wasm ก็เป็นแบบนี้ครับ!! อ่านไม่ออกแน่นอน เพราะเป็น Bytes Code 🙂

Screen Shot 2560-03-05 at 7.03.33 PM.png

ถัดมาเราก็มาเขียน JavaScript ให้การโหลดไฟล์ democ.wasm ซึ่งผมใช้ fetch API ครับและหลังจากนั้นเป็นการเรียกใช้งาน function

Screen Shot 2560-03-05 at 7.06.57 PM.png

จาก Code นี้ในฝั่งของ JavaScript นั้นผมขอแบ่งออกเป็น 4 ส่วนครับ

  1. โหลดไฟล์ .wasm ด้วย fetch API
  2. ทำการประกาศ imports Object เพื่อให้ตัว WenAssembly ทำงานได้ถูกต้อง เช่นการกำหนดขนาดของ  Memory
  3. เป็นการสร้าง Module Object จาก .wasm
  4. เป็น Code ที่ใช้เรียก function “add” ที่เขียนด้วยภาษา C (ในการ Compile นั้นทาง Compiler ได้เติม _ เพื่อเป็น prefix ให้กับชื่อ function ทำให้เราต้องเรียก function นี้ด้วย _add แทน)

ทีนี้ลองมารันดูครับด้วย localhost:8080/demo.html แต่ก่อนอื่นเราต้องมี Browser ที่รองรับก่อน

เตรียม Browser ให้พร้อม

ผมเลือกใช้ Google Chrome Canary Build (ซึ่งเป็น Google Chrome เวอร์ชั่นทดสอบ) ซึ่งตอนนี้เป็นเวอร์ชั่น 59 ครับ เราต้องเปิด flag สำหรับ WebAssembly ด้วยเพราะตอนนี้ยังเป็นแค่ฟีเจอร์สำหรับการทดสอบอยู่ด้วย

chrome://flags/#enable-webassembly

Screen Shot 2560-03-05 at 8.34.54 PM.png

ผลของการทำงานก็จะเห็นได้ว่า function _add นั้นทำการบวกค่าได้อย่างถูกต้อง

Screen Shot 2560-03-05 at 7.11.48 PM.png

สรุป

ก่อนอื่นต้องบอกว่า WebAssembly นั้นเป็นของที่ยังถือว่าใหม่และยังไม่นิ่งเพราะถึงแม้ว่าจะเปิดตัวมาตั้งแต่ปี 2015 แต่จนถึงวันนี้ก็ยังอยู่ในสถานะที่กำลังออกแบบกันอยู่ ซึ่งจากการที่ผมได้ลองอ่านและเล่นๆดูก็พบว่าบทความบนอินเตอร์เน็ตนั้นน้อยมาก กว่าผมจะพอปะติดปะต่อภาพรวมของการทำงานของมันจนมาถึงลองเขียน Code ตัวอย่างดูก็ใช้เวลาอยู่พักนึง แต่ผมว่าเมื่อถึงเวลาที่มันออกสู่สาธราณะเป็น Official Release ฟีเจอร์นี้ก็น่าจะถูกจับตามองอีกครั้งกับการใช้งานหนักๆ เช่น เกมหรืองานคำนวณ รวมทั้งงานที่เน้นกราฟฟิคหนักๆ

Advertisements

TypeScript มาเพิ่มคุณภาพของ Code ด้วย TsLint

Screen Shot 2560-02-04 at 10.23.56 AM.png

Linter นั้นคือเครื่องมือที่ช่วยให้ตรวจสอบลักษณะการเขียน Code ว่าเหมาะสมกับ Best Practices ที่ทาง Community ต่างๆแนะนำหรือไม่ ซึ่งจุดประสงค์หลักเพื่อช่วยให้ Source Code ของทั้งโปรเจคนั้นมีความ

  • อ่านง่าย และไปในทิศทางเดียวกัน
  • ดูแล แก้ไขง่าย
  • แก้ปัญหา Error แบบพื้นฐาน

โดยสำหรับ TypeScript นั้นgเครื่องมือนี้มีชื่อว่า TsLint

 การติดตั้งก็ใช้ npm เจ้าเก่า

$ npm install tslint typescript

จากนั้นก็ทำการสร้าง tslint.json ซึ่งจะเป็นไฟล์หลักที่ใช้ในการ Config ค่าต่างๆของ TsLint

$tslint –init

ลองเปิดดูไฟล์ tslint.json เราก็จะเห็นว่าทางค่าปกติที่ติดตั้งมานั้นมีกฏอะไรบ้าง ซึ่งใน version 4.4.2 ที่ผมใช้นั้นมันซัพพอร์ท JavaScript ด้วย

Screen Shot 2560-02-04 at 9.33.30 AM.png

กับอีกส่วนนึงคือ Node สำหรับ TypeScript ที่ใช้ชื่อ attribute ว่า rules เฉยๆ

Screen Shot 2560-02-04 at 9.36.27 AM.png

ทดสอบกับ Code ตัวอย่าง

ที่นี้มาลองเล่นกันกับ Code ตัวอย่างแบบง่ายๆกับ main.ts

// main.ts
class HERO{
 private name = 'HERO'
 public attack()
 {
 console.log(`${this.name} : do attack`);
 }
}

var player = new HERO();
player.attack();

หลังจาก compiled .ts ออกมาเป็น .js ก็จะออกมาเป็น

// main.js
var HERO = (function () {
 function HERO() {
 this.name = 'HERO';
 }
 HERO.prototype.attack = function () {
 console.log(this.name + " : do attack");
 };
 return HERO;
}());
var player = new HERO();
player.attack();

ลองรันดูก็ได้ผลออกมาตามนี้ครับ ซึ่งก็ถูกต้องดีหมายความว่า Code เรารันได้ดี 🙂

Screen Shot 2560-02-04 at 9.50.44 AM.png

ทีนี้ลองมารัน TsLint เพื่อดูว่า Code ของเรา 10 บรรทัดเนี่ยมันเขียนมาโอเคมั้ยกัน

$ tslint -c tslint.json *.ts -t stylish

ผลออกมากโดนไป 5 เรื่องครับ tslint จะรายงานมาว่าเราเขียนไม่ดียังไง ที่บรรทัดไหน ตัวอักษรที่เท่าไหร่

screen-shot-2560-02-04-at-9-54-26-am

เรื่องที่เราโดนรายงานครั้งนี้คือ

  1. ใช้ var แทนที่จะเป็น let หรือ const เพราะในโลกของ TypeScript เราแนะนำกันแบบนี้
  2. ลืมเว้นวรรค!!
  3. ใส่วงเล็บปีกกาเปิดผิดที่!@!#
  4. ตัวแปร String เราดันใช้ single quote ” แทนที่จะเป็น dobule quotes “” (ตามที่กำหนดไว้ใน tslint.json)
  5. ลืมเครื่องหมาย semi colon

จะเห็นว่าสิ่งที่มันรายงานผลมานั้นก็ดูดีมีประโยชน์ครับ(มั้ย?)

ที่นี้เรามาดู Code หลังจากแก้ไขไปแล้วดีกว่าเนอะ

Screen Shot 2560-02-04 at 10.15.16 AM.png

จากรูปด้านซ้ายและขวาที่เหมือนเล่นเกมจับผิด จะเห็นได้ว่าการทำ Linter นั้นช่วยให้ Code ของเรานั้นดูเป็นระเบียบมากขึ้น ยิ่งในกรณีที่ในโปรเจคมี Developer หลายๆคน อาจะใช้ Linter นั้นจะช่วยให้ Code ที่ถูกเขียนมานั้นเป็นไปในแนวทางเดียวกันมากขึ้น

การทำให้ Software นั้น Maintain ได้ง่ายและมีคุณภาพ เป็นเกียรติ (Duty) ของ Developer นะครับ 🙂

node-ffi เรียก functions ใน dll ด้วย JavaScript กันตรงๆ

จากความเดิมตอนที่แล้วผมเคยเขียนเรื่องการสร้าง Node.js Module ด้วย C++ มาทีนึงแล้ว แต่ถึงอย่างนั้นถ้าเรา
– มี C++ Library อยู่แล้วล่ะ
– หรืออยากทำให้ Node สามารถเรียกใช้งานพวก System API โดยที่ไม่อยากศึกษาการเขียน Node Module แบบ Native
ผมก็ไปเจอว่ามี Community ที่ได้พัฒนา Framework มาตัวนึงซึ่งวันนี้เราจะมาพูดถึงกัน นั่นก็คือ Node-ffi ซึ่งย่อมาจาก Foreign Function Interface

Node-ffi นั้นเป็น Module ที่ทำหน้าที่เป็นตัวกลางในการทำการติดต่อระหว่าง JavaScript Code ไปที่ C++ Library โดยที่เราไม่ต้องเขียน Native Module เอง ประมาณรูป Diagram ด้านล่างครับ

ffi.png

เรามาลองดูการใช้งานกันดีกว่าครับ

ก่อนอื่นเรามี C++ Library ที่เป็น DLL ที่ต้องการจะเรียก ซึ่งผมลองเขียนมาแบบง่ายๆคือ dll ที่มี function ในการ ดึงค่า Version ของ OS

extern "C" DLLIMPORT int getVersion()
{
 DWORD dwVer = ::GetVersion();
 DWORD majorVer = (DWORD)(LOBYTE(LOWORD(dwVer)));
 return majorVer;
};

ซึ่ง API ::GetVersion นั้นเป็นของ Windows SDK ครับ ซึ่งสำหรับฝั่ง C++ ผมได้ทำการ  Compile ออกมาเป็น dll ชื่อ dev.dll

ทีนี้มาลองดูส่วนที่สำคัญของเราก็คือฝั่ง JavaScript

var ffi = require('ffi');

var devModule = ffi.Library('dev', {
 'getVersion': [ 'int', [] ]
});
console.log('Windows version : ' + devModule.getVersion());

จาก Code นี้ก็มี 3 ส่วนหลักๆครับ

  1. require module ‘ffi’
  2. ประกาศการทำ function binding
    ffi.Library('dev', {
      'getVersion': [ 'int', [] ]

    2.1 ทำการ binding กับไฟล์ library ชื่อ dev.dll
    2.2 ทำการ binding กับ function ชื่อ getVersion โดยมี ‘int’ เป็น Type ของ Return Value
    2.3 Function getVersion นี้ไม่มี parameter เลยใส่เป็น []

  3. เรียกใช้ ffi ด้วย  devModule.getVersion()

ผลของการรันก็เป็นดังนี้ครับคือได้ค่า ’10’ มาจาก getVersion

ffi_run.png

นอกจากนี้เรายังสามารถประกาศการทำ binding ทีละหลายๆ function ก็ได้เหมือนกันครับ(ขออนุญาติไม่โชว์ Code ฝั่ง C++ ที่เขียนเพิ่มเพื่อดึงค่า Minor,Build Version) เช่น

var devModule = ffi.Library('dev', {
 'getVersion': [ 'int', [] ] ,
 'getMinorVersion' : [ 'int', [] ],
 'getBuildVersion' : [ 'int', [] ]
});
console.log('Windows version : ' + devModule.getVersion());
console.log('Minor version : ' + devModule.getMinorVersion());
console.log('Build version : ' + devModule.getBuildVersion());

ผลการรันก็ดูดีครับและตรงกับ System Info จริงๆนะ 🙂

ffi_run2.png

สรุป : node-ffi น่าจะเป็นอีกหนึ่งทางเลือกสำหรับคนที่เขียน Node.Js ด้วย Context บางอย่างที่ต้องติดต่อกับ System หรือ OS ระดับ Low Level (เหมือนผม..) โดยที่เรานั้นไม่ต้องมาการเรียนรู้การเขียน Node Module แบบ Native ที่อาจจะมีความซับซ้อนกว่าทั้งในแง่การทำ Mapping พวก Data Types รวมถึงการมานั่งศึกษา V8 API  ซึ่งผมคิดว่า node-ffi อาจจะมีผลกระทบกับ Performance ในการ call function บ้าง แต่ผมก็ยังไม่ได้ลองวัด ทั้งนี้ทั้งนั้นใครมีข้อมูลเพิ่มก็แชร์กันได้ครับ

ทำให้ App บน Windows เป็นสีขาว-ดำ

เนื่องจากว่าผมได้พยายามลองทำให้ Application บน Windows นั้นเปลี่ยนเป็นสีโทนขาว-ดำ เลยอยากจะแชร์สิ่งที่ได้ลองทำนะครับ (ถึงแม้ว่าผลของการ Implement นั้นยังไม่ถูกใจเท่าที่ควร)

ก่อนอื่นเลยผมขอเรียก app นี้ว่า Mourning App และเนื่องจากว่าต้องการทำสำหรับ Windows App ดังนั้นภาษาที่ผมใช้คือ C++ และ Win32 API ซึ่งตัว API ที่ใช้หลักๆคือ Magnification API ซึ่งเป็น Windows API ที่ปกติเอาไว้ทำพวก Tool ที่เป็นแว่นขยายต่างๆ

หลักการของ Mourning App ที่ผมทำมี 4 ขั้นตอน คือ

  1. หา Process ที่เราสนใจจะทำการ apply การทำภาพขาวดำก่อน

    API ที่ผมใช้ส่วนนี้คือ

    ::EnumProcesses ซึ่งทำให้เราได้จำนวน Process ที่กำลังรันอยู่ทั้งหมดมาพร้อมทั้ง Process ID ซึ่งเราจะใช้เอาไว้หาชื่อ Process ที่เราสนใจได้

  2. หา Window Handle (hwnd) ที่มันทำการแสดงผลอยู่ (visible) ของ Process นั้นๆ

    Code หลักๆที่ใช้ก็คือ  ::EnumWindows
    ซึ่งจากนั้นใน Callback ของ EnumWindowsProc นั้นจะได้ hwnd มาเรื่อยๆซึ่งผมจำการเช็ค

    if (!::IsWindow(hwnd) && !::IsWindowVisible(hwnd))
    return true;

  3. Render ทับตำแหน่ง application จริงๆด้วย Magnifier window พร้อมกับแปลงให้เป็นสีแบบ Gray Scale

    ส่วนนี้เป็นส่วนสำคัญที่สุด ซึ่งใช้ Magnification API โดยการสร้าง Window ด้วย Style : MS_CLIPAROUNDCURSOR

    m_hwndMag = CreateWindow(WC_MAGNIFIER, TEXT(“MagnifierWindow”),
    WS_CHILD | MS_CLIPAROUNDCURSOR | WS_VISIBLE

  4. ทำการ Refresh รูปบ่อยๆเพื่อให้ภาพเนียนที่สุดเวลา Application มีการ update หน้าจอ

    ส่วนนี้ไม่มีอะไรมากก็คือการตั้ง Timer เพื่อทำการ Refresh UI ครับแต่เราจะ Refresh เฉพาะ window ไม่ใช่ทั้งหน้าจอ Desktop

ตัวอย่างที่ได้ครับ

vscode
vscode in grayscale
chrome.png
Chrome เป็นสีเทา แต่ Edge ยังเป็นสีปกติ
ffx2.png
เกม FFX-2 ก็ทำให้ขาว-ดำ ได้นะครับ

ที่นี้มาดูผลที่ยังไม่น่าพอใจใน Implement ครั้งนี้ครับ

  1. ตัว render ภาพขาว-ดำนั้นเป็น Top Window ซึ่งทำให้ถ้ามี App ที่เปิดทับมันก็จะเป็นสีขาว-ดำด้วย
  2. ช้า เนื่องจากการ refresh นั้นบ่อยๆมีผลกับ Performance ทำให้ภาพมี delay บ้าง
  3. CPU ขึ้นตลอดเวลา 5% เนื่องจากต้อง query Process ตลอดเวลาในการเช็คว่ามี Window ของ Process ที่เราจะทำการ render ขาว-ดำ เปิดมาใหม่รึเปล่า

สุดท้ายนี้ ใครสนใจอยากดูตัวอย่างก็ Github เลยครับผม https://github.com/anurocha/mourning-win-app

เข้าสู่ C++ ยุคใหม่กับ Module System สำหรับ C++ 17/20

ไม่ยอมน้อยหน้าภาษา Modern เพราะหนึ่งใน Feature ที่มีการพูดถึงกันมากของมาตรฐานใหม่ของ C++ 17 ก็คือเรื่อง Module System (Link) ซึ่งเป็นแนวคิดทำให้ Library เป็น Module แบบจริงจัง โดยที่ทางกลุ่ม C++ Working Group ได้นำเสนอมานานแล้ว และมีแผนที่จะเอาเข้ามาเป็นส่วนหนึ่งของ C++ 17 แต่เหมือนว่าไม่น่าจะทัน C++ 17 แล้วครับ สรุปแล้วตอนนี้ Feature นี้อยู่ในขั้น Technical Specification ซึ่งน่าจะออกจริงใน C++ 20 (เลขข้างหลังเป็นเลขที่ เช่น 2017 หรือ 2020)

เป้าหมายของ Module System คือทำให้ C++ นั้นทำการ Compile ได้เร็วขึ้นและทำให้ Code นั้นมีการจัดการระดับ Component ได้ง่ายขึ้น เพราะปัจจุบัน #include นั้นใช้งานปนไปหมดทั้ง Headers, Inlines รวมทั้งบางทีมี Implemenation กันเลยทีเดียว

Microsoft นั้นได้ออก Preview สำหรับการทดลอง Module ใน Visual Studio 2015 Update 1+ มาลองดูกันเลยดีกว่า

ก่อนอื่นเลยครับ เนื่องจากว่า Visual Studio ในส่วนของ IDE นั้นยังไม่ Support ดังนั้นเราจะต้องทำการ Compile กับ Build ผ่าน Command Line นะครับ

สร้าง Module

ในการสร้าง Module นั้นให้เราสร้างไฟล์ใหม่มา ซึ่งโดยทั่วไปจะนิยมใช้ไฟล์ .ixx (ผมเดาว่ามาจาก Interface++)
เรามาสร้าง Module เอาไว้ Convert ค่าง่ายๆกัน

ไฟล์ converter.ixx

module converter;
export int CtoB(int x)
{
    return x + 543;
}

จาก code นี้จะเป็นการประกาศ Module ชื่อ converter ซึ่งมี function ‘CtoB’ ที่ทำการแปลง ค.ศ. ไป เป็น พ.ศ. ที่จะ export ออกไปให้ Code อื่นใช้

จากนั้นเราต้อง compile ด้วย commandline แบบนี้

cl /c /experimental:module converter.ixx

สิ่งที่ได้ก็คือไฟล์ converter.ifc กับ converter.obj

converter.png

เรียกใช้ Module

ที่นี้มาในส่วนของ Code หลักที่มี main entry point กันครับ ผมตั้งชื่อไฟล์ว่า main.cpp

ไฟล์ main.cpp

#include <iostream>
import converter;
int main()
{
 int year;
 std::cout << "Enter Year : ";
 std::cin >> year; 

 int bc = CtoB(year);
 std::cout << "Thai year is " << bc << std::endl;
 return 0;
}

Code ในส่วนนี้มีการเรียกใช้ Module ชื่อ ‘converter’ ด้วย keyword ที่ชื่อ import จากนั้นก็จะเรียกใช้ function ที่ชื่อ CtoB() ได้ทันทีเลยครับ

แน่นอนว่าเราต้อง compile ด้วย command line เช่นเคยโดยต้องระบุ converter.ifc เป็น parameter ของ module ที่จะเรียกใช้

cl /c /experimental:module /module:reference converter.ifc main.cpp

เมื่อรันเสร็จก็จะได้ main.obj มาครับ

main.png

ที่นี้จะเป็นว่าไม่มี .exe ให้เรา….สิ่งที่ต้องทำคือการสร้าง .exe ด้วย

link *.obj /OUT:main.exe

link.png

ทดสอบ

ลองรัน main.exe ที่ได้มาครับ ทำงานถูกต้องนะ 🙂

out.png

ลองด้วย Class

จากตัวอย่างข้างบนนั้นเป็นการสร้าง Module ด้วยการ export แค่ function แต่ถ้าเราอยากที่จะ  export Class ล่ะ เราก็ทำได้ครับ เช่น สร้าง Class  converter โดยมี method 2 ตัวให้เรียกใช้

module converter;
export namespace converterUtil
{
 class converter
 {
 public:
 int CtoB(int year)
 {
 return year + 543;
 }

 int CelsiusToFahrenheit(int c)
 {
 return (c * 1.8) + 32;
 }
 };
}

มาดูที่ main.cpp เราก็ทำการ import มาใช้และสร้าง Object ได้เลย เช่นใน ‘convt’ ตาม Code ด้านล่างนี้

#include <iostream>
import converter;
int main()
{
 converterUtil::converter convt;

 int year;
 std::cout << "Enter Year : ";
 std::cin >> year; 

 std::cout << "Thai year is " << convt.CtoB(year) << std::endl;

 int cel;
 std::cout << "Enter Temp in Celsius : ";
 std::cin >> cel; 
 std::cout << "Temp in Fahrenheit is " << convt.CelsiusToFahrenheit(cel) << std::endl;

 return 0;
}

ผลที่ได้ก็ Work ดีครับ!!

outex.png

สรุปแล้ว C++ Module น่าจะช่วยให้ C++ Developer ออกแบบและทำงานกับ Code ได้เป็นระเบียบเรียบร้อยขึ้น

และอีกอย่างคือจริงๆเท่าที่ผมลองในการสร้าง Module ถ้ามันมีใช้ header ตัวอื่นผมก็ยังทำให้มันเวิร์คไม่ได้นะ จึงต้องยกตัวอย่างแบบง่ายๆแบบนี้ครับ ซึ่งหวังว่าตัวจริงออกมาคงไม่วุ่นวายมากนะ

ณ. ตอนนี้เราก็มาเฝ้ารอ C++ 20 กันเลยกัย Module System!!

ปล. ดู Code ได้ที่ https://github.com/anurocha/cpp_module เลยครับผมอัพไว้ละ

JS++ อะไรกันนี่…

jspp_logo

เมื่อวันก่อนผมอ่าน Twitter แล้วมันก็เด้งบทความเกี่ยว JS++ มาให้อ่าน http://sdtimes.com/the-case-for-js-plus-plus/ ซึ่งเนื้อหาหลักๆที่ผมเข้าใจคือ ทางผู้พัฒนาต้องการอุดช่องว่างของ JavaScript ซึ่งหลักๆก็คือเรื่อง Type และ Object Oriented  ซึ่งโปรเจคแนวนี้ก็มีเยอะมากในวงการเช่น Dart หรือ TypeScript

ส่วน JS++ เองนั้นผู้พัฒนาคือ บริษัท Onux ซึ่งมี Official Site อยู่ที่ https://www.onux.com/jspp/
Platform ที่ทาง JS++ รองรับในตอนนี้คือ Windows กับ Linux เท่านั้น และในปัจจุบันนี้ อยู่ที่ Version 0.4.1 ซึ่งเป็น Early Access Preview อยู่

เมื่อ Install เสร็จก็จะได้ไฟล์ประมาณนี้

jspp_files.png

ลองเช็ค version ดูด้วย  js++ –version ก็ได้เป็น 0.4.1

jspp_ver.png

หลักการทำงานของ JS++ นั้นก็คือเราต้องเขียน Code ด้วย Systax ของ JS++ จากนั้นทำการ Compile ให้ออกมาเป็นไฟล์ .js ที่ Browser เข้าใจ

ที่นี้ลอง Hello World ง่ายๆ ด้วยการสร้างไฟล์ test.jspp

external document;

document.write("Hello World!");

ลอง Compile กันดูครับ

jspp_compiledไฟล์ที่ออกมาก็หน้าตาแบบนี้ครับ ซึ่งเป็นสิ่งที่ js เข้าใจ

// Compiled with JS++ v.0.4.1

!function(){document.write("Hello World!");}();

งั้นลองกับ Node.js หน่อยดีกว่า

import Convert;

external require;
external http = require("http");
external console;

string hostname = '127.0.0.1';
int port = 1337;

http.createServer(void(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}).listen(port, hostname, void() {
console.log("Server running at http://" + hostname + ":" + Convert.toString(port) + "/");
});

Compile มาได้แบบนี้ (ดีจริง minify มาให้พร้อม)

// Compiled with JS++ v.0.4.1

!function(){var http=require("http");var hostname='127.0.0.1';var port=1337|0;http.createServer(function(req,res){res.writeHead(200,{'Content-Type':'text/plain'});res.end('Hello World\n');}).listen(port,hostname,function(){console.log("Server running at http://"+hostname+":"+(port+"")+"/");});}();

ลองรันดูก็ WORK ดีครับ

jspp_nodejs.png

ที่นี้ผมลองเอา Code จากหน้า Offical Page ที่มี Class มาลองอีกทีครับ ปรากฏว่า Compile Error เพราะหา Class ไม่เจอ…!@#$

jspp_cls.png

สรุป…ผมว่าสำหรับ Build นี้อาจจะยังไม่ถึงเวลาของ JS++ ในการใช้งานจริงครับ และผมก็คิดว่าทางตัวโปรเจคนี้ก็ยังความท้าทายในการเป็น Framework ที่ฮิตอยู่คือ

  1. ไม่เป็น Open Source
  2. ไม่มี บ.ยักษ์ใหญ่ช่วยหนุน
  3. ไม่มี Roadmap ชัดเจนสำหรับ Release ถัดๆไป

ผมคิดว่า ณ วันนี้ถ้าต้องการมองหาทางเลือกอื่นในการพัฒนา App หรือ Service โดยไม่ต้องใช้ JavaScript ตรงๆ ลองมอง TypeScript หรือ Dart ดีกว่าครับ…(ส่วนตัวตอนนี้ศึกษา TypeScript ครับ)

C++ ภาษานี้ก็ยัง Powerful อยู่เช่นเดิม

c_0

ถ้ามีคนมาถามผมว่าอยากเริ่มเขียนโปรแกรมจะเริ่มจากอะไร ผมก็จะตอบว่า ลองเขียน Java, C# ดูซึ่งเป็น OOP เต็มรูปแบบ มีเครื่องมือครบ และมี Syntax ที่ดีมาก หรือว่าพวกภาษา Script เช่น JavaScript, Python ก็ได้ เพราะจะได้เป็นการหัดคิดแบบเป็น Logic และฝึกแก้ปัญหา

แต่ถ้า ถามว่าอยากเขียนโปรแกรมให้เก่งแบบมองภาพรวมของ Software Architecture ออกจะต้องยังไง
ผมก็จะตอบว่าเขียน C++ ดู

ถึงแม้ว่าภาษา C จะเกิดมาตั้งแต่ปี ค.ศ. 1972 และ C++ มาตอน 1983 แต่ภาษานี้ก็ยังคงความนิยมและคุ้มค่าต่อการศึกษาครับ

เพราะ…C++

  1. เป็นภาษาที่อยู่ระดับเกือบระดับต่ำสุดเป็นรองแค่ Machine Code กับ Assembly ทำให้เราต้องรู้ว่า CPU มันทำงานยังไง
  2. เป็นภาษาที่ใกล้ชิดกับ OS ทำให้เราต้องรู้ว่า OS แต่ละแบบทำงานยังไงมีส่วนประกอบอะไรบ้างสำหรับโปรแกรมหรือ App ของเรา เช่นการจัดการ Process, Thread, File System, Memory, การทำงานระหว่าง Process (IPC)
  3. ไม่ค่อยมี Tool หรือ Function สำเร็จรูปมาให้แบบ Built-In ทำให้การที่เราจะเขียนอะไรง่ายๆ เช่นจะเขียนแปลง String ก็ต้องเขียนเองเยอะ ซึ่งข้อดีคือทำให้เข้าใน Logic/Algorithm ได้ดีขึ้น และมีนิสัยไม่ขี้เกียจที่จะลงแรงเองถึงแม้งานที่ดูเหมือนง่ายอาจจะต้องเขียนกัน 20-30 บรรทัด
  4. ไม่มี Memory Management ที่ฉลาดๆ เราที่จะเขียนก็ต้องฉลาดที่จะใช้เอง ต้องรู้ว่า Memory เก็บยังไงหลังจากที่ทำการ Allocate แล้ว และต้องรู้ว่าจะคืน Memory ให้ระบบตอนไหน
  5. เป็นภาษาที่ถูกต่อยอดไปเป็นภาษาสมัยใหม่หลายๆภาษา เช่น Java, C#, Objective-C, Swift, PHP, Python, Perl, Ruby, JavaScript และอื่นๆอีกมาก ทำให้เราสามารถไปศึกษาภาษาพวกนี้ได้เร็วขึ้น(จริงๆนะ)
    เปรียบเทียบกับทำให้เหมือนเรารู้ภาษาละตินซึ่งเป็นรากฐานของภาษาในยุโรปเกือบทั้งหมด!
  6. ทำให้รู้กระบวนการของการ Compile โปรแกรมตั้งแต่ เขียน Code ไปจนได้ไฟล์ Executable ออกมา
  7. เข้าใจการทำงานของ Framework หลายๆอย่างในปัจจุบัน เช่น OS, Web Browser, .NET Framework หรือ JVM รวมทั้ง Game Engine ต่างๆ และยังใช้เขียนต่อกับ Hardware ด้วย
  8. ส่วนมากจะเป็นสะพานเชื่อมการทำงานระหว่าง Technology เช่นเขียน .NET app ให้คุยกับ Web
  9. Performance ถึงแม้ว่าทุกวันนี้ CPU เราจะแรง แต่ถ้าต้องการรีด CPU ทุก clock cycle การใช้ C++ ก็ช่วยได้นะครับ
  10. Debug ได้ถึง Memory รวมทั้งสามารถ Deassembly Code มาดูเพื่อทำ Reverse Engineer ได้ ถ้าเราเก่งพอ :p
  11. เขียนได้หลาย Paradiam เช่น Imperative, Object-Oriented, Generic Programming (และทำให้ Code มั่วดีด้วยครับถ้าเขียนบนกันทุก Paradiam 555)
  12. ที่สำคัญ ภาษา C++ นั้นยังมีการพัฒนาอยู่เสมอซึ่ง version หลังๆก็คือ C++11/C++14 และที่กำลังจะมาคือ C++17 (เลขข้างหลังคือเลขปี ค.ศ.ที่จะออก) ซึ่งสิ่งที่เพิ่มเข้ามาทำให้เขียน Code ได้ง่ายขึ้น เช่นเดียวกับภาษายุคใหม่แหละครับ

 

C++ is still ROCK (as always)!

ปล.

  • บทความนี้ความเห็นส่วนตัวนะครับ 🙂
  • C++ เป็นภาษาแรกที่ผมอยากเขียนหลังจากที่ผมรู้จักคอมพิวเตอร์ ตอน ม.ปลาย (เพราะอยากเขียนเกม) แต่ไม่สำเร็จเพราะเข้าไม่ถึงผมเลยหนีไปเขียนเวป PHP, C#, Java ตอนเรียนมหาวิทยาลัย
  • C++ เป็นภาษาที่ใช้ในโปรเจคแรกของชีวิตการทำงาน Developer ของผม