Skip to content

Experimental Features

Torsten Paul edited this page Sep 6, 2021 · 6 revisions

Experimental features are meant to give early access to new or changed functionality while the features are still not fully committed. This means there can still be changes to input parameters, output results or anything related to the functionality. It might even happen the feature is never published in a release, although that is not the intention.

Note that it's not the intention to completely hide experimental features when disabled or in a release build. The main effect is to make it unavailable for use. The code is still compiled and part of the application and certain parts of experimental features may still be in effect (e.g. changes to the language parser).

How does it work from user perspective

The preferences dialog of the development snapshot builds has an additional tab called Features which lists all available experimental features with a checkbox to enable/disable this feature. This setting works only in GUI mode.

From command line experimental features can be enabled via the --enable option. This option does not work in GUI mode.

Defining a new experimental feature

All experimental features are defined in feature.{h,cc}. Adding a new entry is as simple as listing a new definition in the header file feature.h

  static const Feature ExperimentalTextMetricsFunctions;

and initializing this object in feature.cc

  const Feature Feature::ExperimentalTextMetricsFunctions("textmetrics",
        "Enable the <code>textmetrics()</code> and <code>fontmetrics()</code> functions.");

The first string is the key used in the --enable command line option and the UI configuration file / registry entry

[feature]
textmetrics=true

Marking code as experimental

Modules

For modules, the feature just needs to be added to the BuiltinModule constructor call, the normal definition for assert looks like

  Builtins::init("assert", new BuiltinModule(builtin_assert),
    {
      "assert(boolean)",
      "assert(boolean, string)",
    });

adding the feature will mark it experimental, issuing a warning if it's called while the feature is disabled.

  Builtins::init("assert", new BuiltinModule(builtin_assert, &Feature::ExperimentalAssertExpression,
    {
      "assert(boolean)",
      "assert(boolean, string)",
    });

Functions

Declaring functions as experimental works essentially the same as with modules, by adding the feature to the BuiltinFunction constructor call.

  Builtins::init("textmetrics", new BuiltinFunction(&builtin_textmetrics, &Feature::ExperimentalTextMetricsFunctions),
    {
      "textmetrics(text, size, font, direction, language, script, halign, valign, spacing) -> object",
    });

Other code

If the experimental features is not a built-in module or function, the status can be checked via the Feature object.

  if (Feature::ExperimentalLazyUnion.is_enabled()) {
    ...
  }

Test suite

The test suite normally builds with experimental features enabled, but test cases are run without the --enable flag set.

If there are test cases for experimental features, the associated --enable flag needs to be added to the CMakeLists.txt file in the tests foder

  if (${EXPERIMENTAL_TEST} EQUAL -1)
    set(EXPERIMENTAL_OPTION "")
  else()
    # add global experimental options here
    set(EXPERIMENTAL_OPTION ${EXPERIMENTAL_OPTION} "--enable=lazy-union" "--enable=textmetrics")
  endif()

and the test case needs to be flagged as experimental

  experimental_tests(dumptest_text-metrics)

There is usually no more separation, the normal run has no experimental features enabled, the test run flagged as experimental gets all the currently available experimental features enabled (as defined in the EXPERIMENTAL_OPTION shown above).

Clone this wiki locally