Skip to content

Instantly share code, notes, and snippets.

@AriFordsham
Last active October 12, 2021 12:48
Show Gist options
  • Save AriFordsham/8fe2696b887415ec3781be1bb25e75c0 to your computer and use it in GitHub Desktop.
Save AriFordsham/8fe2696b887415ec3781be1bb25e75c0 to your computer and use it in GitHub Desktop.
Programming vs. scripting languages

Programming languages vs. scripting languages

Programming languages began as a veneer over assembly language. They were close to the machine and tedious to program - the state of compiler technology was not advanced enough to support the many features that programmers would find useful, even if they could envision them.

To plug this gap, the idea of an interpreted language was born. This provided a way to write small programs - scripts - in an easier style. Performance was not critical, as the scripts were generally for simple tasks, and may only needed to have run once or occasionally. An entire folklore of interpreter writing techniques developed - it was much easier to implement useful, time-saving features in an interpreter than in a compiler.

At this point, the types of language supported by interpreters and compilers were very different. Interpreted programs were not considered mature enough for production use, hence they were known as 'scripting' languages, as opposed to compiled languages used for 'programming'. They could generally be distinguished as follows:

Programming languages Scripting languages
Code processed by compiler to generate executable Code written by programmer executed directly
Machine code executed by hardware
Runs independently on the machine
Code executed by interpreter
Requires a copy of the interpreter to run
Executes entry-point (main) function Runs top-to-bottom
Strongly typed Untyped
Prioritizes performance Proiritizes ease-of-use
Low-level High-level
C, C++, Swift, Go, Rust Bash, VB6, JavaScript, PHP, Perl, Ruby

These differences are driven both by the differences between compiler and interpreter technology at the time, and the intended purpose of the languages.

Compiled languages rose up from very close to the metal. The objects were bytestrings, and the types provided interpretation for these bytestrings. For interpreters, it was often easier to use the same data structure for all objects rather than implement a type system. In addition, the correctness benefits of strong types (slight as they may have been at the time) were more important for programs that would be distributed to others for use in production, while for quick scripts it was deemed more important to free the programmer from the burden of thinking about types.

Many early interpreters where 'one-pass', reading in and executing the file at the same time. This means th ile was executed top-to-bottom, giving the program a less structured feel. This also helped contributed to the moniker 'scripting'. On the other hand, object files produced by comilers typically began with headers and static data followed by a series of functions, so it made sense to begin execution with a 'special' function.

However, language implementation technology has come a long way since then, and many of the limitations no longer exist, and indeed, many more recent languages 'mix and match' these design decisions. It's now much more difficult to 'pin down' a language into one category or another. The four technical distinctions in the upper half of the table, while interrelated, are conceptually independent, leading to a possible design space of 24 = 16 points, even before we get to hybrid options.

TODO: Survey of popular languages, and languages that represent interesting points in this space

Interesting as-yet-unexplored points in the design space

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment