Paradigm | Multi-paradigm: functional, imperative, logic, meta, modular, object-oriented, reflective |
---|---|
Family | Lisp |
Designed by | PLT Inc. |
Developer | PLT Inc. |
First appeared | January 28, 1995 |
Stable release | |
Typing discipline | Dynamic, static, strong |
Platform | x86, PowerPC, SPARC, MIPS, ARM |
OS | Cross-platform |
License | MIT or Apache 2.0 [2] |
Filename extensions | .rkt [3] |
Website | racket-lang |
Major implementations | |
Racket, RacketScript Racket to JavaScript (ES6) compiler, Pycket a Racket implementation using RPython. | |
Dialects | |
Typed Racket, FrTime, Lazy Racket, Scribble | |
Influenced by | |
Eiffel, [4] Scheme | |
Influenced | |
Clojure, [5] Rust, [6] [7] Scheme (R6RS) [8] |
Racket is a general-purpose, multi-paradigm programming language. The Racket language is a modern dialect of Lisp and a descendant of Scheme. It is designed as a platform for programming language design and implementation. [9] In addition to the core Racket language, Racket is also used to refer to the family of programming languages [10] and set of tools supporting development on and with Racket. [11] Racket is also used for scripting, computer science education, and research.
The Racket platform provides an implementation of the Racket language (including a runtime system, [12] libraries, and compiler supporting several compilation modes: machine code, machine-independent, interpreted, and JIT) along with the DrRacket integrated development environment (IDE) written in Racket. [13] Racket is used by the ProgramByDesign outreach program, which aims to turn computer science into "an indispensable part of the liberal arts curriculum". [14] [15]
The core Racket language is known for its extensive macro system which enables creating embedded and domain-specific languages, language constructs such as classes or modules, and separate dialects of Racket with different semantics. [16] [17] [18] [19]
The platform distribution is free and open-source software distributed under the Apache 2.0 and MIT licenses. [20] Extensions and packages written by the community may be uploaded to Racket's package catalog.
Matthias Felleisen founded PLT Inc. in the mid 1990s, first as a research group, soon after as a project dedicated to producing pedagogic materials for novice programmers (lectures, exercises/projects, software). In January 1995, the group decided to develop a pedagogic programming environment based on Scheme. Matthew Flatt cobbled together MrEd, the original virtual machine for Racket, from libscheme, [21] wxWidgets, and a few other free systems. [22] In the years that followed, a team including Flatt, Robby Findler, Shriram Krishnamurthi, Cormac Flanagan, and many others produced DrScheme, a programming environment for novice Scheme programmers and a research environment for gradual typing. [13] The main development language that DrScheme supported was named PLT Scheme.
In parallel, the team began conducting workshops for high school teachers, training them in program design and functional programming. Field tests with these teachers and their students provided essential clues for directing the development.
Over the following years, PLT added teaching languages, an algebraic stepper, [23] a transparent read–eval–print loop, a constructor-based printer, and many other innovations to DrScheme, producing an application-quality pedagogic program development environment. By 2001, the core team (Felleisen, Findler, Flatt, Krishnamurthi) had also written and published their first textbook, How to Design Programs , based on their teaching philosophy.
The Racket Manifesto [9] details the principles driving the development of Racket, presents the evaluation framework behind the design process, and details opportunities for future improvements.
The first generation of PLT Scheme revisions introduced features for programming in the large with both modules and classes. Version 42 introduced units – a first-class module system – to complement classes for large scale development. [24] The class system gained features (e.g. Java-style interfaces) and also lost several features (e.g. multiple inheritance) throughout these versions. [16] The language evolved throughout a number of successive versions, and gaining milestone popularity in Version 53, leading to extensive work and the following Version 100, which would be equivalent to a "1.0" release in current popular version systems.
The next major revision was named Version 200, which introduced a new default module system that cooperates with macros. [24] In particular, the module system ensures that run-time and compile-time computation are separated to support a "tower of languages". [25] Unlike units, these modules are not first-class objects.
Version 300 introduced Unicode support, foreign library support, and refinements to the class system. [24] Later on, the 300 series improved the performance of the language runtime with an addition of a JIT compiler and a switch to a default generational garbage collection.
By the next major release, the project had switched to a more conventional sequence-based version numbering. Version 4.0 introduced the #lang
shorthand to specify the language that a module is written in. Further, the revision introduced immutable pairs and lists, support for fine-grained parallelism, and a statically-typed dialect. [26]
On 7 June 2010, PLT Scheme was renamed Racket. [27] The renaming coincided with the release of Version 5.0. Subsequently, the graphical user interface (GUI) backend was rewritten in Racket from C++ in Version 5.1 using native UI toolkits on all platforms. [22] Version 5.2 included a background syntax checking tool, a new plotting library, a database library, and a new extended REPL. [28] Version 5.3 included a new submodule feature for optionally loaded modules, [29] new optimization tools, a JSON library, and other features. [30] Version 5.3.1 introduced major improvements to DrRacket: the background syntax checker was turned on by default and a new documentation preview tool was added. [31]
In version 6.0, Racket released its second-generation package management system. As part of this development, the principal DrRacket and Racket repository was reorganized and split into a large set of small packages, making it possible to install a minimal racket and to install only those packages needed. [32]
Version 7 of Racket was released with a new macro expander written in Racket as part the preparations for supporting moving to the Chez Scheme runtime system and supporting multiple runtime systems. [33] [34] On 19 November 2019, Racket 7.5 was released. The license of Racket 7.5 was less restrictive. They use now either the Apache 2.0 license or the MIT license. [35] [36]
On 2021 February 13, Racket 8.0 was released. Racket 8.0 marks the first release where Racket with the Chez Scheme runtime system, known as Racket CS, is the default implementation. Racket CS is faster, easier to maintain and develop, backward-compatible with existing Racket programs, and has better parallel garbage collection. [37]
Racket's core language includes macros, modules, lexical closures, tail calls, delimited continuations, [38] parameters (fluid variables), software contracts, [39] green threads and OS threads, [40] [41] [42] and more. The language also comes with primitives, such as eventspaces and custodians, which control resource management and enables the language to act like an operating system for loading and managing other programs. [12] Further extensions to the language are created with the powerful macro system, which together with the module system and custom parsers can control all aspects of a language. [43] Most language constructs in Racket are implemented as macros in the base language. These include a mixin class system, [16] a component (or module) system as expressive as opaque ascription in the ML module system, [17] and pattern matching.
Further, the language features the first contract system for a higher-order programming language. [44] Racket's contract system is inspired by the Design by Contract work for Eiffel and extends it to work for higher-order values such as first-class functions, objects, reference cells, and so on. For example, an object that is checked by a contract can be ensured to make contract checks when its methods are eventually invoked.
Racket includes both bytecode and JIT (JIT) compilers. The bytecode compiler produces an internal bytecode format run by the Racket virtual machine, and the JIT compiler translates bytecode to machine code at runtime.
Since 2004, the language has also shipped with PLaneT, a package manager that is integrated into the module system so that third-party libraries can be transparently imported and used. Also, PLaneT has a built-in versioning policy to prevent dependency hell. [45]
At the end of 2014, much of Racket's code was moved into a new packaging system separate from the main code base. This new packaging system is serviced by a client program named raco. The new package system provides fewer features than PLaneT; a blog post by Jay McCarthy on the Racket blog explains the rationale for the change and how to duplicate the older system. [46]
The features that most clearly distinguish Racket from other languages in the Lisp family are its integrated language extensibility features that support building new domain-specific and general-purpose languages. Racket's extensibility features are built into the module system to allow context-sensitive and module-level control over syntax. [18] For example, the #%app
syntactic form can be overridden to change the semantics of function application. Similarly, the #%module-begin
form allows arbitrary static analysis of the entire module. [18] Since any module can be used as a language, via the #lang
notation, this effectively means that virtually any aspect of the language can be programmed and controlled.
The module-level extensibility features are combined with a Scheme-like hygienic macro system, which provides more features than Lisp's s-expression manipulation system, [47] [48] Scheme 84's hygienic extend-syntax macros, or R5RS's syntax-rules. Indeed, it is fair to say that the macro system is a carefully tuned application programming interface (API) for compiler extensions. Using this compiler API, programmers can add features and entire domain-specific languages in a manner that makes them completely indistinguishable from built-in language constructs.
The macro system in Racket has been used to construct entire language dialects. This includes Typed Racket, which is a gradually typed dialect of Racket that eases the migration from untyped to typed code, [49] Lazy Racket—a dialect with lazy evaluation, [50] and Hackett, which combines Haskell and Racket. [51] The pedagogical programming language Pyret was originally implemented in Racket. [52] [53]
Other dialects include FrTime (functional reactive programming), Scribble (documentation language), [54] Slideshow (presentation language), [55] and several languages for education. [56] [57]
Racket's core distribution provides libraries to aid the development of programming languages. [18] Such languages are not restricted to s-expression based syntax. In addition to conventional readtable-based syntax extensions, the directive #lang
enables the invocation of arbitrary parsers, which can be implemented using the parser tools library. [58] See Racket logic programming for an example of such a language.
The language platform provides a self-hosted IDE [13] named DrRacket, a continuation-based web server, [59] a graphical user interface, [22] and other tools. As a viable scripting tool with libraries like common scripting languages, it can be used for scripting the Unix shell. It can parse command-line arguments and execute external tools.
DrRacket (formerly DrScheme) is widely used among introductory computer science courses that teach Scheme or Racket and is lauded for its simplicity and appeal to beginner programmers. The IDE was originally built for use with the TeachScheme! project (now ProgramByDesign), an outreach effort by Northeastern University and a number of affiliated universities for attracting high school students to computer science courses at the college level.
The editor provides highlighting for syntax and run-time errors, parenthesis matching, a debugger and an algebraic stepper. Its student-friendly features include support for multiple "language levels" (Beginning Student, Intermediate Student and so on). It also has integrated library support, and sophisticated analysis tools for advanced programmers. Further, module-oriented programming is supported with the module browser, a contour view, integrated testing and coverage measurements, and refactoring support. It provides integrated, context-sensitive access to an extensive hyper-linked help system named "Help Desk".
DrRacket is available for Windows, macOS, Unix, and Linux with the X Window System and programs behave similarly on all these platforms.
Here is a trivial "Hello, World!" program:
#lang racket"Hello, World!"
Running this program produces the output:
Here is a slightly less trivial program:
#lang racket(require2htdp/image)(letsierpinski([n8])(if(zero?n)(triangle2'solid'red)(let([t(sierpinski(-n1))])(freeze(abovet(besidett))))))
This program, taken from the Racket website, draws a Sierpinski triangle, nested to depth 8.
Using the #lang
directive, a source file can be written in different dialects of Racket. Here is an example of the factorial program in Typed Racket, a statically typed dialect of Racket:
#lang typed/racket(:fact(Integer->Integer))(define(factn)(if(zero?n)1(*n(fact(-n1)))))
Racket currently has two implementations. Both support Linux, Windows and MacOS on a variety of architectures and are supported as at version 8.8 (2023). The default implementation uses the Chez Scheme incremental compiler and runtime. The alternate implementation generates platform-independent bytecode and uses Just-in-time compilation to generate machine code as it is loaded. [60]
In addition, there are experimental implementations:
Apart from having a basis in programming language theory, Racket was designed as a general-purpose language for production systems. Thus, the Racket distribution features an extensive library that covers systems and network programming, web development, [59] a uniform interface to the underlying operating system, a dynamic foreign function interface, [63] several flavours of regular expressions, lexer/parser generators, [58] logic programming, and a complete GUI framework.
Racket has several features useful for a commercial language, among them an ability to compile standalone executables under Windows, macOS, and Unix, a profiler and debugger included in the integrated development environment (IDE), and a unit testing framework.
Racket has been used for commercial projects and web applications. A notable example is the Hacker News website, which runs on Arc, which is developed in Racket. Naughty Dog has used it as a scripting language in several video games. [64]
Racket is used to teach students algebra through game design in the Bootstrap program. [65]
Lisp is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation. Originally specified in the late 1950s, it is the second-oldest high-level programming language still in common use, after Fortran. Lisp has changed since its early days, and many dialects have existed over its history. Today, the best-known general-purpose Lisp dialects are Common Lisp, Scheme, Racket, and Clojure.
In computer programming, a macro is a rule or pattern that specifies how a certain input should be mapped to a replacement output. Applying a macro to an input is known as macro expansion.
OCaml is a general-purpose, high-level, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features. OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, and others.
In computer science, a preprocessor is a program that processes its input data to produce output that is used as input in another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers. The amount and kind of processing done depends on the nature of the preprocessor; some preprocessors are only capable of performing relatively simple textual substitutions and macro expansions, while others have the power of full-fledged programming languages.
Bytecode is a form of instruction set designed for efficient execution by a software interpreter. Unlike human-readable source code, bytecodes are compact numeric codes, constants, and references that encode the result of compiler parsing and performing semantic analysis of things like type, scope, and nesting depths of program objects.
Programming languages can be grouped by the number and types of paradigms supported.
Metaprogramming is a computer programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modify itself, while running. In some cases, this allows programmers to minimize the number of lines of code to express a solution, in turn reducing development time. It also allows programs more flexibility to efficiently handle new situations with no recompiling.
A domain-specific language (DSL) is a computer language specialized to a particular application domain. This is in contrast to a general-purpose language (GPL), which is broadly applicable across domains. There are a wide variety of DSLs, ranging from widely used languages for common domains, such as HTML for web pages, down to languages used by only one or a few pieces of software, such as MUSH soft code. DSLs can be further subdivided by the kind of language, and include domain-specific markup languages, domain-specific modeling languages, and domain-specific programming languages. Special-purpose computer languages have always existed in the computer age, but the term "domain-specific language" has become more popular due to the rise of domain-specific modeling. Simpler DSLs, particularly ones used by a single application, are sometimes informally called mini-languages.
In computer science, extensible programming is a style of computer programming that focuses on mechanisms to extend the programming language, compiler, and runtime system (environment). Extensible programming languages, supporting this style of programming, were an active area of work in the 1960s, but the movement was marginalized in the 1970s. Extensible programming has become a topic of renewed interest in the 21st century.
Language-oriented programming (LOP) is a software-development paradigm where "language" is a software building block with the same status as objects, modules and components, and rather than solving problems in general-purpose programming languages, the programmer creates one or more domain-specific languages (DSLs) for the problem first, and solves the problem in those languages. Language-oriented programming was first described in detail in Martin Ward's 1994 paper Language Oriented Programming.
Matthias Felleisen is a German-American computer science professor and author. He grew up in Germany and immigrated to the US in his twenties. He received his PhD from Indiana University Bloomington under the direction of Daniel P. Friedman.
In computer science, the syntax of a computer language is the rules that define the combinations of symbols that are considered to be correctly structured statements or expressions in that language. This applies both to programming languages, where the document represents source code, and to markup languages, where the document represents data.
The ProgramByDesign project is an outreach effort of the PLT research group. The goal is to train college faculty, high school teachers, and possibly even middle school teachers, in programming and computing.
Matthew Flatt is an American computer scientist and professor at the University of Utah School of Computing in Salt Lake City. He is also the leader of the core development team for the Racket programming language.
The expression problem is a challenging problem in programming languages that concerns the extensibility and modularity of statically typed data abstractions. The goal is to define a data abstraction that is extensible both in its representations and its behaviors, where one can add new representations and new behaviors to the data abstraction, without recompiling existing code, and while retaining static type safety. The statement of the problem exposes deficiencies in programming paradigms and programming languages, and as of 2023 is still considered unsolved, although there are many proposed solutions.
Racket has been under active development as a vehicle for programming language research since the mid-1990s, and has accumulated many features over the years. This article describes and demonstrates some of these features. Note that one of Racket's main design goals is to accommodate creating new programming languages, both domain-specific languages and completely new languages. Therefore, some of the following examples are in different languages, but they are all implemented in Racket. Please refer to the main article for more information.
Red is a programming language designed to overcome the limitations of the programming language Rebol. Red was introduced in 2011 by Nenad Rakočević, and is both an imperative and functional programming language. Its syntax and general usage overlaps that of the interpreted Rebol language.
Robert Bruce Findler, colloquially known as "Robby", is an American computer scientist, currently, a professor of computer science at Northwestern University. He is also a member of the PLT group and, as such, responsible for the creation and maintenance of DrRacket. In addition to DrRacket, Findler has contributed numerous components to Racket and supervises its Web-based software library, called PLaneT. Findler is also a leading team member of the ProgramByDesign project.
A language workbench is a tool or set of tools that enables software development in the language-oriented programming software development paradigm. A language workbench will typically include tools to support the definition, reuse and composition of domain-specific languages together with their integrated development environment. Language workbenches were introduced and popularized by Martin Fowler in 2005.
The standard file extension for a Racket program file is ".rkt". The extensions ".ss", ".scm", and ".sch" are also historically popular.
1958 | 1960 | 1965 | 1970 | 1975 | 1980 | 1985 | 1990 | 1995 | 2000 | 2005 | 2010 | 2015 | 2020 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LISP 1, 1.5, LISP 2(abandoned) | |||||||||||||||
Maclisp | |||||||||||||||
Interlisp | |||||||||||||||
MDL | |||||||||||||||
Lisp Machine Lisp | |||||||||||||||
Scheme | R5RS | R6RS | R7RS small | ||||||||||||
NIL | |||||||||||||||
ZIL (Zork Implementation Language) | |||||||||||||||
Franz Lisp | |||||||||||||||
Common Lisp | ANSI standard | ||||||||||||||
Le Lisp | |||||||||||||||
MIT Scheme | |||||||||||||||
XLISP | |||||||||||||||
T | |||||||||||||||
Chez Scheme | |||||||||||||||
Emacs Lisp | |||||||||||||||
AutoLISP | |||||||||||||||
PicoLisp | |||||||||||||||
Gambit | |||||||||||||||
EuLisp | |||||||||||||||
ISLISP | |||||||||||||||
OpenLisp | |||||||||||||||
PLT Scheme | Racket | ||||||||||||||
newLISP | |||||||||||||||
GNU Guile | |||||||||||||||
Visual LISP | |||||||||||||||
Clojure | |||||||||||||||
Arc | |||||||||||||||
LFE | |||||||||||||||
Hy | |||||||||||||||
Chialisp |