Iman Tung

Today I found out that json.Marshal() weirdly return null for an empty slice but make sense.

var slice []string
b, _ := json.Marshal(slice)
fmt.Println(string(b)) // Output: null

The workaround is to initiate empty slice using make() function.

var slice []string
slice = make([]string, 0)
b, _ := json.Marshal(slice)
fmt.Println(string(b)) // Output: []

I thought make() will make fixed length slice and append() will trigger an error, but it totally fine. That's why in go they called it to slice instead of an array, the behavior is slightly different with the fixed-length array in another language.

var slice []string
slice = make([]string, 0)
fmt.Println(len(slice)) // Output: 0

slice = append(slice, "some-string")
fmt.Println(len(slice)) // Output: 1

b, _ := json.Marshal(slice)
fmt.Println(string(b)) // Output: ["some-string"]

Thanks to Dan Ott’s article for the insight

Previously published in at 18 Apr 2019



“If you don’t know how compilers work, then you don’t know how computers work. If you’re not 100% sure whether you know how compilers work, then you don’t know how they work.” — Steve Yegge

Like a few weeks ago I did research about interpreters for a DSL-related project.

This approach called Tree-Walking Interpreter is the simplest way to make an interpreter

  1. Free text/grammar: literally what you type
  2. Lexer/lexical analysis: text to tokens
  3. Tokens/Lexemes: chunks of your syntax
  4. Parser: tokens to the syntax tree
  5. Syntax Tree/Abstract Syntax Tree or AST: model represented operator with its precedence level and associativity
  6. Evaluator: running through AST and execute the operation.

For those who looking for more resources to start learning on this subject, I recommend Ruslan Blog and Writing An Interpreter In Go

Previously published in at 20 Dec 2017



This kind of query may useful for unit testing.

Query 1: This is working for most SQL

SELECT 'Anto' as name, 12 as age

Query 2:

FROM (values ('Anto', 12),('Linda', 9), ('Mike', 10) ) AS q (name, age)

Query 3: Single column with a lot of data

SELECT id FROM regexp_split_to_table('1,2,3,4,5,7,8,9', ',') AS id

Query 4: To expect more seconds for the query. pg_sleep usually used at blind SQL injection.

SELECT 1 as id, pg_sleep(10)

Previously published in at 15 Sep 2017



I try to run a jar file on my user laptop and found that the terminal java version is different from the mac OS version. Downloading JRE is not helping because it’s not set environment variable $JAVA_HOME

This instruction may help to set $JAVA_HOME without downloading JDK.

  1. Go to System Preference > Java

2. Check or update your java version on Update tab

3. On Java tab, click button View to see the java installation location.

4. Copy the path and remove bin/java

/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home

5. Setup environment variable on your mac

$ echo "export JAVA_HOME=/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home" >> ~/.bash_profile
$ source .bash_profile

6. Check your java version

$ java -version

Previously published in at 13 Sep 2017



So I got this CSV file generated by dbeaver to trigger some automation task but my code can’t process it. The file is perfect until I open it on excel and I see this ï"¿. So this is the culprit. Actually, it's quite famous and known as Byte Order Mark (BOM)

Unicode text can optionally start with a byte order mark (BOM) to signal the endianness of the file or stream. Its code point is U+FEFF. In UTF-32 for example, a big-endian file should start with 00 00 FE FF; a little-endian should start with FF FE 00 00.

In the case of DBeaver, we can uncheck Insert BOM option when generating CSV.

Previously published in at 27 Aug 2017



Iman Tung

Iman Tung

Technology to write, life to grateful. Overthinking is good, only if it has the output. Fundamental is the main concern.