+ 1 Is Felix a Scripting Language?

There has been debate on the Felix language mailing list as to whether Felix is a scripting language. In part this arises from the claim on the website that Felix is the fastest scripting language on Earth.

Some users think Felix is a high performance compiled language. Indeed the slogan hyperlight speed suggests performance better than C (the speed of light, our benchmark).

However the startup speed for one off programs is slow because the Felix code is first translated to C++ by the Felix compiler and then to machine binaries by your C++ compiler.

And there's no REPL. So it can't be a scripting language!

+ 1.1 What makes a scripting language?

In the old days, scripting languages such as Perl were interpreted. They ran slow, but they ran immediately. They were dynamically typed, or just had one or two types, usually string and integer, with a dictionary (hash) and array thrown in.

However all modern scripting languages are based on true compilers. They compile to byte code and run on some kind of VM. Python works this way, and even TCL switched to bytecode compilation.

One only has to look at Ocaml to see the fallacy of the distinction. Ocaml has a bytecode compiler {ocamlc}, and it runs a REPL {ocaml} but it also has a high performance native code compiler {ocamlopt} which is so fast its doubtful for a small program you could even notice the compilation delay.

Furthermore, compilation systems, even slow ones, typically use dependency checking and caching at various stages to improve turn around, and Felix is no exception.

On the other hand few people would claim Java is a scripting language, but Java compilers typically emit bytecode.

So really, whilst the slow startup time of fresh Felix programs is a concern, it isn't a categorical discriminating factor. Run a Felix script a second time and it runs immediately!

+ 1.2 Dynamic Typing

Many so called scripting languages are dynamically typed. Felix uses strong static typing, so it can't be a scripting language, right?

Well it isn't that clear to me! People usually associate the lack of type annotations with scripting languages, rather than the fact that the type system will detect type errors early. But Ocaml has type inference and programs can be written without mentioning any types. That's a cool counter example: static typing but no annotations.

On the other hand many people working with Python and Javascript are crying out static typing. Experiments have been done adding optional static typing to these systems, or writing a compiler translating a slightly better structured language down to the base language. This has been done in many experiments for Javascript .. even Ocaml can be translated to Javascript.

What's more, most people would agree syntax errors at startup type make sense even for dynamic languages, and it isn't clear that static typing checks are a lot more than an extension of parsing.

On the other hand, almost all languages are dynamic and involve dynamic typing, even languages like Ocaml and Haskell. Every time your code interprets data and makes choices based on that, you have dynamic typing. The simple fact is that there's no hard and fast distinction between type information and data: constraints on data, such as the format of a stream of text, are type constraints which are beyond the static type system to check, so the checks are done dynamically at run time by your code, and that's dynamic typing!

So whilst it is common, dynamic typing can't be a pre-requisite for classing a language as a scripting language.

+ 1.3 Deployment simplicity.

In my opinion one of the key properties of a scripting language is not to be found in the language itself, but rather the tools that are used to deploy it. Traditionally a script in Perl or Python can just be run, without explicitly invoking a complex compilation and linkage script.

Since Felix tools can simply run Felix script, exactly the same way as Python can:

flx filename.flx

and do compilation, caching, and dependency checking in the background to speed up the compilation proces, Felix makes good claim to be a scripting language. It can be used the same way as other scripting languages!

+ 1.4 Eval

A more serious language based property of scripting languages is the ability of the language to generate code in that language at run time and then execute it. Perl and Python can do the generation with considerable difficulty, but they can run code prepared in a file manually more easily with an {eval} or {exec} command.

Still, in Python at least most programmers do not use such dangerous features and many would like to disable it just to improve the security of their programs.

Of course, the language in which this property is paramount, and intrinsic to the design, is of course Scheme. Scheme data is lists, represented as S-expressions, and so are Scheme programs.

However, eval like features are a serious impediment and don't even work properly in modern Python. Its compiler does optimisations which are seriously compromised by sticking with dynamic lookup of symbols in a table, so it doesn't, and consequently eval only works in suitably prepared environments.

On the other hand, Felix can invoke its own compiler just as any programming language can, and it can translated Felix code to a shared library which can then be dynamically loaded. So Felix can do eval too!

In all these cases, especially Felix, sharing data between the host and client scripts is the key issue. It's easier with dynamic lookup in a symbol table, and lets face it that's how {dlopen()}/{dlsym()} actually work! The fact is that even C can do eval, and you can always devise encodings which provide enough run time type information to perform whatever calculations you like.

Now you can argue the run time type information is not naturally present in compiled languages, but this is not really true: even C++ has RTTI.

So really, eval is a strong indicator, but it isn't quite enough for a categorical denial!

+ 1.5 Core data types.

Scripting languages, probably due to weak dynamic typing, typically only support a few data types: integers, floats, and strings together with arrays, dictionaries, and possibly some kind of class or structure.

Some more modern ones like Javascript also provide functional values (closures).

It is, I believe, a key feature of scripting languages that they have the eval like property that they have good string handling. Files are strings, and program script is also a string. Regexps are strings and do string pattern matching. Shell commands are also strings.

So in my view we can knock Ocaml out of the scripting language category because it has terrible string handling! Of course you can write a more comprehensive library but it doesn't come out of the box.

Felix on the other hand has awesome string handling! It is even better than Perl.

+ 1.6 Separate Interfaces.

Perhaps the single most important property of scripting languages, as opposed to compiled languages, is the ability to devise and use library code, and build whole programns, without separate compilation or separate interfaces. Compiled languages usually separate the implementation code from the interface, either requiring separate specifications for the interfaces and build scripts to support separate compilation and linkage.

Whilst Felix does support separate compilation, at its heart it is a whole program analyser and for simple scripts, no separate compilation is required and there is no need for separate interfaces.

Separate interfaces do provide many advantages, apart from the ability to do separate compilation. The most crucial of these is the elimination of the need to provide dependencies of the implementation in the interface: typically only type related dependencies are required.

When working with Felix, the ease of prototyping without needing separate interfaces is balanced against the need to provide all the dependencies of the implementation. This drags in seemingly unrelated code implicity, at least exposing class names unexpectedly. If the class is open by default, its public contents are also exposed, opening the door for hijacking.

Never the less this speaks most loudly for the fact that current Felix really is a scripting language. You not only don't need to declare function prototypes, you can't.

It is perhaps this aspect of scripting languages that makes them less suitable for programming in the large. Even systems like Python which require explicit local importation of modules fail to properly isolate implementation details. Felix classes has similar capabilities, whilst include files do not.