How compatible is Ling?

Ling is a reincarnation of Erlang VM and, as such, it must exhibit behaviour sufficiently similar to its widely used ancestor, BEAM. An extensive testing has been conducted to demonstrate the similarity. The results of the testing are summarized in the table below.

Test suite Total Ok Failed Skipped
lists_SUITE 68 68
tuple_SUITE 12 12
list_bif_SUITE 6 6
binary_SUITE 32 27 2 3
bs_bincomp_SUITE 6 5 1
bs_bit_binaries_SUITE 11 10 1
bs_construct_SUITE 21 19 1 1
bs_match_bin_SUITE 3 3
bs_match_int_SUITE 8 8
bs_match_misc_SUITE 16 16
bs_match_tail_SUITE 3 3
bs_utf_SUITE 7 7
exception_SUITE 10 10
big_SUITE 14 13 1
float_SUITE 11 8 1 2
fun_SUITE 18 10 1 7
guard_SUITE 6 5 1
num_bif_SUITE 9 9
ref_SUITE 1 1
ets_SUITE 108 79 12 17
file_SUITE 65 50 5 10
gen_tcp_api_SUITE (9p) 10 6 4
gen_tcp_echo_SUITE (9p) 9 9
gen_tcp_api_SUITE (lwIP) 10 9 1
gen_tcp_echo_SUITE (lwIP) 9 9
re_SUITE 15 15
decode_packet_SUITE 9 9



  1. bad_binary_to_term_2 attempts to start a new node (skipped).
  2. obsolete_funs tests obsolete funs represented as binaries (skipped).
  3. gc_test uses undocumented process_info(Pid, binary) call (skipped).
  4. terms_float relies on snprintf() when converting a double to an external term format. The Ling’s snprintf() implementation produces a slightly different string that results in mismatch after unpacking. The possible cause are compiler options related to the floating-point math (fails).
  5. deep creates a structure a million levels deep. The routine copying terms between heaps is recursive and thus unable to handle the structure. A system_limit exception is thrown (fails).


  1. tracing uses call tracing not supported in Ling. A simpler call tracing is possible in the new VM (skipped).


  1. append uses undocumented and unsupported erts_debug() calls (skipped).


  1. bs_add uses a compiler. While it is possible to import all compiler modules into Ling, it seems an overkill to make a few tests run. All interpreter modules are imported as many more tests use them (skipped).
  2. huge_binary is unable to build a binary because the maximum number of bits for a binary in Ling is 7 bits smaller than in BEAM (4294967288 vs 4294967295). Smaller maximum bit size means the ability to use 32-bit size representation in many places (fails).


  1. big_literals uses compiler (skipped).


  1. fp_drv uses driver subsystem (skipped).
  2. fp_drv_thread uses driver subsystem (skipped).
  3. cmp_bignum exhibits different rounding behaviour not related to Erlang VM. For instance, an integer value of 288230376151711744 is (automatically) rounded in C to 288230376151711750.0 in Ling and to 288230376151711740.0 in BEAM. It may be dependent on the compiler options (fails).


  1. fun_to_port uses unsupported port_command() call (skipped).
  2. refc uses undocumented fun_info(Fun, refc) call. It may represent an implementation detail related to funs (skipped).
  3. refc_ets see refc (skipped).
  4. refc_dist see refc (skipped).
  5. const_propagation see refc (skipped).
  6. t_arity starts a new node (skipped).
  7. t_fun_info see refc (skipped).
  8. t_is_function2 treats certain 2-tuples as funs. Ling does not support obsolete funs (fails).


  1. guard_bifs directly tests two floating-point values for equality. The values appear to be (slightly) different (fails).


  1. t_delete_object uses undocumented ets:info(T, stats) call to make an implementation-dependent check; works if the check is removed.
  2. t_delete_all_objects see t_delete_object.
  3. smp_insert uses undocumented ets:info(T,stats) call.
  4. smp_select_delete same as smp_insert.
  5. memory test is a joke; it uses hardcoded values for various undocumented parameters.
  6. heir uses undocumented erts_debug:get_internal_state() to reset the pid numbering to ease reuse of pids; hangs because the function is not supported; other bits of the case work.
  7. t_match_spec starts a node to get external things, works if these small dependencies are removed.
  8. types starts a node to make external things; this useful case should be reimplemented without the dependency.
  9. fixtable_insert fails only the last small case that verifies that semi-deleted entries should be deleted immediately when the table is unfixed. This requires additional full-scan through the table or maintaining a list of semi-deleted entries. Ling keeps semi-deleted entries when the table is unfixed and removes them opportunistically.
  10. partly_bound verifies the perfromance gain for key bound match specs; faster code for such match specs are not implemented yet – they still use the full scan.
  11. t_whitebox uses a continuation generated by ets:match/3 in the call to ets:select/1; such use is not supported.
  12. t_repair_continuation tests a function that is not required for Ling as a match spec gets compiled every time before use; to be stubbed later to make Mnesia, etc happy.


  1. exclusive O_EXCL mode is not supported by diod (fails).
  2. truncate Ling allows truncating a file opened read-only. It may be possible to implement the restriction but the potential gain vs the overhead involved is small (fails).
  3. file_info_times the access and modification times need timezone information that is not yet handled in Ling properly (fails).
  4. delayed_write delayed_write option is not supported by Ling (fails).
  5. read_ahead read_ahead option is not supported by Ling (fails).
  6. read_line see read_ahead (fails).

The modifications to the source code of file_SUITE.erl are mostly related to the fact that Ling allows deleting the current directory (if empty) and that os:type() returns ‘ling’. Also ‘enotempty’ is returned instead of ‘eexist’ when renaming a directory to an existing non-empty directory. Several modifications were made to decrease the number of iterations and operate on smaller data segments to avoid ‘no memory’ exceptions.

gen_tcp_api_SUITE (9p)

  1. t_shutdown_write, t_shutdown_both, t_shutdown_error test unsupported inet:shutdown() function (fails).
  2. t_fdopen tries to retrieve a file descriptor to base a socket on (fails).

gen_tcp_echo_SUITE (9p)

The source code of the test suite was modified to exclude checks for the correct packing/unpacking for the following packet types: sunrm, cdr, line, http, http_bin, asn1. The support for some of the excluded packet types, such as http/http_bin, will be added later.

gen_tcp_api_SUITE (lwIP)

  1. t_fdopen creates a socket from a file descriptor. Ling does not have file descriptors (fails).

gen_tcp_echo_SUITE (lwIP)

The source code of the test suite was modified to exclude larger packet sizes (65531, 65535, and 70000). In lwIP the len parameters of various API calls has uint16_t type. The maximum packet size tested is 65000.


The source code of the test suite was modified to exclude the checks for locale-dependent regular expressions. Such regular expressions are unsupported by Ling as there is no concept of locale. Another small modification deals with easing of a check for an error returned when compilation space overflows.