Hog is the coolest programming language in the world (we're biased).
It is being used to build our CDP product, which you can follow along with in GitHub.
Note: Hog shouldn't be confused with HogQL, our SQL-like query language used inside PostHog. If you're looking to query data in PostHog, see those docs.
How to run Hog
To run Hog, first, you need to clone and set up PostHog locally. The repo has VMs to run the source code and complied bytecode as well as example files. The default VM relies on PostHog's Python dependencies, but we also have a Typescript VM that relies on those dependencies.
Once you have PostHog set up, go into the repo and run bin/hog
with a .hog
file.
cd posthogbin/hog hogvm/__tests__/mandelbrot.hog
You can add the --debug
flag to step through and see the stack trace.
Compiling Hog
You can compile a .hog
file to a .hoge
executable with bin/hoge
.
bin/hoge hogvm/__tests__/mandelbrot.hog
You can then run the complied .hoge
file automatically with bin/hog
.
bin/hog hogvm/__tests__/mandelbrot.hoge
Syntax
Comments
Hog comments start with //
. You can also use SQL style comments with --
or C++ style multi line blocks with /*
.
// Hog comments start with //-- You can also use SQL style comments with --/* or C++ style multi lineblocks */
Variables
Use :=
to assign a value to a variable because =
is just equals in SQL and HogQL.
// assign 12 to myVarlet myVar := 12myVar := 13myVar := myVar + 1
Comparisons
On top of standard comparisons, like
, ilike
, not like
, and not ilike
work.
let myVar := 12print(myVar = 12 or myVar < 10) // prints trueprint(myVar < 12 and myVar > 12) // prints falselet string := 'mystring'print(string ilike '%str%') // prints true
Regex
Compares strings against regex patterns. =~
matches exactly, =~*
matches case insensitively, !~
does not match, and !~*
does not match case insensitively.
print('string' =~ 'i.g$') // trueprint('string' !~ 'i.g$') // falseprint('string' =~* 'I.G$') // true, case insensitiveprint('string' !~* 'I.G$') // false, case insensitive
Arrays
Supports both dot notation and bracket notation.
let myArray := [1,2,3]print(myArray.1) // prints 2print(myArray[1]) // prints 2
Tuples
Supports both dot notation and bracket notation.
let myTuple := (1,2,3)print(myTuple.1) // prints 2print(myTuple[1]) // prints 2
Objects
You must use single quotes for object keys and values.
let myObject := {'key': 'value'}print(myObject.key) // prints 'value'print(myObject['key']) // prints 'value'
Strings
Strings must always start end end with a single quote. Includes f-string support.
let str := 'string'print(str || ' world') // prints 'string world', SQL concatprint(f'hello {str}') // prints 'hello string'print(f'hello {f'{str} world'}') // prints 'hello string world'
Functions
Can only be defined at the top scope. See Hog's standard library for a list of built-in functions.
fn addNumbers(num1, num2) {let newNum := num1 + num2return newNum}print(addNumbers(1, 2))
Logic
let a := 3if (a > 0) {print('yes')}
Nulls
let a := nullprint(a ?? 'is null') // prints 'is null'
While loop
let i := 0while(i < 3) {print(i) // prints 0, 1, 2i := i + 1}
Hog's standard library
Hog's standard library includes the following functions and will expand. To see the the most update-to-date list, check the Python VM's stl/__init__.py
file.
concat(...args)
match(string, regex)
toString(arg)
toUUID(arg)
toInt(arg)
toFloat(arg)
ifNull(value, alternative)
length(stringOrArray)
empty(arg)
notEmpty(arg)
tuple(...args)
lower(str)
upper(str)
reverse(str)
print(...args)
jsonParse(str)
jsonStringify(obj)
base64Encode(str)
base64Decode(str)
tryBase64Decode(str)
encodeURLComponent(str)
decodeURLComponent(str)
replaceOne(string, needle, replacement)
replaceAll(string, needle, replacement)