OpenResty Fanlang™ User Manual

fanlang - A Perl 6 dialect for implementing other DSLs

Table of Contents


$ cat
my $who = "world";
say "hello, $who!"

$ fan
hello, world!


Fanlang is a optimizing compiler that converts a dialect of Perl 6 into standalone Lua code targeting OpenResty.

The motivation behind the fanlang compiler are:

  1. We want to be much more productive when writing OpenResty-based software that is not performance sensitive, like a DSL compiler. Perl 6 (or even Perl 5) is much more expressive and much more powerful than Lua, especially for text processing tasks and implementing transcompilers. But Lua has its own strength in performance and simplicity. So we write fanlang that compiles Perl 6 into Lua for OpenResty.

  2. We want the compiling speed or compiler performance to be (much) faster than the counterparts implemented in Perl 5.

Back to TOC

Perl 6 features that will never be implemented

  • multi methods and multi subs.
  • Perl 6 regexes (we use Perl 5 regexes and our own fanlang rule syntax).

Back to TOC

Language features incompatible to Perl 6


Fanlang does not support the builtin Perl 6 class Seq yet. In cases where Rakudo returns a Seq object, fanlang produces a List object instead.

Back to TOC


Fanlang uses Perl 5 compatible regexes by default in its regexes. This means that the Perl 6 regex adverb :P5 is always in effect in fanlang code. Also, whitespace characters are not significant t in fanlang’s Perl 5 compatible regexes, unless the regex adverb :s is specified.

Back to TOC


Fanlang uses its own grammar rule syntax inspired by Parse::RecDescent and Pegex.

The “actions” class fed into Grammar objects’ parse() method can inherit from the builtin class Actions, which provide useful methods like get-line() for fetching the current line number in the input being parsed.

When the FANLANG_DEBUG=1 system environment variable is specified, the fanlang grammar engine will generate tracing output for debugging parsers written in fanlang.

Back to TOC

Error Handling

When an error happens in the slurp() builtin or a Grammar object’s parse() method, the corresponding builtin fanlang routine will not throw an exception like Perl 6, instead, it returns Nil and sets the special variable $! to the error string.

Back to TOC


The .gist() output for some primitive values, like Nil, False, and True, are in all lower case, that is, their gist outputs are nil, false, and true, respectively.

Back to TOC


The global variable @*ARGS() is not allowed to used in any fan source that is imported by use statement.

Back to TOC

Genuine builtins


The test-regex(regex) subroutine accepts a fanlang string and checks whether it is a valid Perl compatible regex. Returns True if yes; returns Nil and sets $! to the error string otherwise.

Back to TOC


Accepts an arbitrary fanlang value as the sole argument. Returns True when the value is a “primitive value”, e.g., a boolean, a number, a string, or just Nil. Returns False otherwise. Neither objects, types, arrays, nor hashes are considered “primitive values”.

Back to TOC


Accepts a fanlang string as a file name. Returns True when the file exists; False otherwise.

Back to TOC

class Attribute


This read-only attribute returns the bare name of the current Attribute object, without the sigil and twigil parts.

Back to TOC


Yichun Zhang (agentzh) <>

Back to TOC

Copyright (C) 2016-2021, OpenResty Inc. All rights reserved.

This software is proprietary and must not be redistributed or shared at all.

Back to TOC