npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

descript-lang

v0.2.0

Published

Descript - Developer's Essential Script

Readme

Descript - Developer's Essential Script

Descript® is a type-implied language that commits to the human expression and embraces the progress in coding features endorsed by ECMA

The rules governing the language are:

  • closest syntax to the human writing
  • everything has substance
  • direct conversion to TypeScript or to JavaScript

Motto

Descript®, also called 'the 'triple E language', has the human-centric motto 'Express.Embrace.Endorse.'

Example

Following is a comparison between a code for fetching RSS news feeds in Descript® and the resulting code in TypeScript.

Descript

import fetch from 'node-fetch'
import { parseStringPromise } from 'xml2js'

// a type describing the shape and the field types of an article
type Article as {
    title: string,
    date: Date,
    link: string,
    image: string,
    description: string
}

// A type alias representing an article map
type ArticleMap = Map<string, Article> default = new Map()

// An enumeration of image identifier strings 
enum ImageType
    Thumb = 'media:thumbnail',
    Media = 'media:content'
endenum

// This function retrieves the feeds from a RSS URL, extracting, normalizing and returning an article map object
async func Promise<ArticleMap> fetchRss (string url = '')
    // Create a new map with URLs as keys and articles as values
    const ArticleMap newsMap = default(ArticleMap)
    try
        // get the XML from the address URL
        const response = await fetch(url)
        const xmlText = await response.text()
        // Convert the XML to a JavaScript object tree
        const result = await parseStringPromise(xmlText, { explicitArray: false })
        // Safely access the array of article items
        const items = result?.rss?.channel?.item || []
        for const item of items do
            // create a default empty article object
            const Article article = default(Article)
            // Extract and normalize the article data and find article images
            Object.keys(item).forEach(func (key)
                switch (key)
                case 'link':
                case 'title':
                case 'description':
                    article[key] = item[key]
                case 'pubDate':
                    article.date = new Date(item[key])
                endswitch
            endfunc)
            if item[ImageType.Thumb]?.$?.url do
                article.image = item[ImageType.Thumb].$.url
            else
                if item[ImageType.Media]?.$?.url do
                    article.image = item[ImageType.Media].$.url
                endif
            endif
            // Assign a new link -> article entry into the article map
            newsMap.set(article.link, article)
        endfor
    catch (error)
        // Treat errors when retrieving the data
        console.error('Error fetching RSS feed:', error)
    endtry
    return newsMap
endfunc

// test the RSS fetching function
fetchRss('http://feeds.bbci.co.uk/news/science_and_environment/rss.xml')
.then(func (news)
    // Here is the code managing the retrieved articles
    console.info(news)
endfunc)
.catch((func (error)
    // here is the code coping with any rejected promise
    throw error
endfunc)

TypeScript

import fetch from 'node-fetch';
import { parseStringPromise } from 'xml2js';

// a type describing the shape and the field types of an article
interface Article {
    title: string,
    date: Date,
    link: string,
    image: string,
    description: string
}

// A type alias representing an article map
type ArticleMap = Map<string, Article>;

// An enumeration of image identifier strings 
enum ImageType {
    Thumb = 'media:thumbnail',
    Media = 'media:content'
}

// This function retrieves the feeds from a RSS URL, extracting, normalizing and returning an article map object
const fetchRss = async (url: string = ''): Promise<ArticleMap> => {
    // Create a new map with URLs as keys and articles as values
    const newsMap: ArticleMap = new Map();
    try {
        // get the XML from the address URL
        const response = await fetch(url);
        const xmlText = await response.text();
        // Convert the XML to a JavaScript object tree
        const result = await parseStringPromise(xmlText, { explicitArray: false });
        // Safely access the array of article items
        const items = result?.rss?.channel?.item || [];
        for (const item of items) {
            // create a default empty article object
            const article: Article = {
                title: '',
                date: new Date(),
                link: '',
                image: '',
                description: ''
            };
            // Extract and normalize the article data and find article images
            Object.keys(item).forEach((key) => {
                switch (key) {
                case 'link':
                case 'title':
                case 'description':
                    article[key] = item[key];
                break;
                case 'pubDate':
                    article.date = new Date(item[key]);
                break;
                }
            });
            if (item[ImageType.Thumb]?.$?.url) {
                article.image = item[ImageType.Thumb].$.url;
            }
            else {
                if (item[ImageType.Media]?.$?.url) {
                    article.image = item[ImageType.Media].$.url;
                }
            }
            // Assign a new link -> article entry into the article map
            newsMap.set(article.link, article);
        }
    }
    catch (error) {
        // Treat errors when retrieving the data
        console.error('Error fetching RSS feed:', error);
    }
    return newsMap;
};

// test the RSS fetching function
fetchRss('http://feeds.bbci.co.uk/news/science_and_environment/rss.xml')
.then((news) => {
    // Here is the code managing the retrieved articles
    console.info(news);
})
.catch((error) => {
    // here is the code coping with any rejected promise
    throw error;
});

Table of contents

[TOC]

Syntax

The language mimics the phrasing of the Latin writing with less punctuation and with the standard amount of symbolic notation. It uses keywords, commas, parentheses, and line breaks for creating the structure. Dots, semicolons,, square or curly braces, indents are not used for phrasing. The full stop that you’d put after a sentence, or the semicolon put after each statement elsewhere, is here a new-line keyboard input.

The keywords are lowercase shorthand or short English words.

Statements

A statement is the equivalent of a written phrase which usually carries a specific message. There are two categories of statements: keyword statements which always begin with a keyword, call simply statements, and expressions which don’t begin with a keyword and generally are computations.

The (keyword) statements are divided between block statements and non-block statements. Another division is between single-line and multi-line statements.

The block statements have two parts besides the keyword: the conditions or requirements part, and the body or bodies part.

The non-block statements have one part besides the keyword: a value or a list of values or homogenous parameters (e.g. identifiers with optional initializers).

The following rules for the Descript® syntax apply:

  • a block statement ends with a matching keyword of the form end<keyword>
  • the conditions/requirements part of a block statement is enclosed in parentheses only for special cases such as a function definition, for the rest being followed by the keyword do
  • if the conditions part of a block statement is multipart (like e.g. for, its parts are separated by commas
  • if a block statement is multi-line, its body/bodies must begin on a new line separately from the rest of the statement
  • If one single-line block statement which has a non-empty body, is first on the line and, evidently ends the line, its ending keyword may be omitted
  • The non-block statements do not have an ending keyword and their eventual list of values is comma-separated
  • The separator for consecutive statements/expressions on the same line is comma

Syntax recommendations:

  • the ending keyword for a multi-line block statement should sit separately on its own line
  • if a non-block statement has a multi-line aspect (because e.g. of a multi-line initializer), it’s recommended to be single within the statement (e.g. a variable declaration), if possible
  • avoid bi-directional spanning of the code (on both the horizontal and on the vertical), prefer multi-line instead of long single-line
  • if needed, use parentheses in any part of the phrase, for disambiguation

Sentence continuation

An alternate way to write a non-block statement having only one keyword is to put all the other phrase/parameters enclosed in parentheses. This works both for a short or for a multi-line phrase.

<keyword> (<parameters>)

Runtime environment

the vocabulary and the semantics of a programming language are indirectly affected by the design of its runtime model. Better said, both the syntax and the runtime model are determined by the design and the concepts of the language. The runtime environment of the Descript®language is the JavaScript runtime.

All JavaScript runtime features apply, such as: variables management, reference counting, garbage collection, runtime exceptions etc. Yet, as we will see, Descript®greatly reduces the runtime uncertainty and even paves the way for a more optimizable runtime.

Incremental transition

Because Descript®performs a straightforward translation to TypeScript or to JavaScript, fragments of JavaScript or even TypeScripts syntax may be used, temporarily, where an equivalent Descript®language construct is not yet implemented. Furthermore, all before mentioned languages have a common C-syntax root, so most expressions and certain constructs are mutually interoperable.

Types

In Descript®, the types of the variables are always specified although not always written down. There is no uncertainty regarding variables type starting from the source code.

The built-in types of Descript® language are the same as the built-in types of JavaScript except null and undefined. the special TypeScript function return type of void is also allowed.

Descript® follows the C-like syntax of optionally specifying the type of a variable or of a function, by putting the type before the identifier name but after the keyword, with the form:

<keyword>[ <typespec>] <identifier> ...[ , ...]

For a list of identifiers, the canonical form of the syntax requires that the type specification appears in front of each identifier, as opposed of being in front of the whole list.

Type grouping

In variable declarations, one can group multiple variables of the same type by simply putting a type in front of a list of variables which is enclosed in parentheses.

<vardecl> <typespec> (<name1>, <name2>[, ...])

Compound types

For working with the user-defined types, also called compound types, Descript® adopts two basic concepts from TypeScript: the type definition which is the equivalent of an interface, and the type operation which is the equivalent of a type alias. The syntax for each of these two statements is the following:

type <identifier>[ <modifiers>] as <objectspec>
type <identifier>[ <modifiers>] = <typeexpr>

The component parts of these statements have a similar meaning to those in TypeScript.

Everything has substance

One major problem when running a program is that several variables do not hold the appropriate content and structure at the beginning of their lifespan, but rather after a while.. JavaScript tries to mitigate this problem by allowing dynamic membership in objects and by providing the optional chaining operator, while TypeScript enforces the structure checking when a variable first gets used in the source code, neither of these approaches really solving the cause. Another issue is that meaning full source info like data types, access modifiers, startup setup etc. is not carried over in the runtime, by default. In Descript®, the following general rule applies:

Anything that is defined at source code time is retrievable at run time.

Default value

Because in Descript® any new variable is guaranteed to have a non-void type, and taking in account the enounced general rule of the language, the following consequences apply:

  • any new variable must have an initial non-void value
  • the variable declaration must contain either an initializer or a data type, or both
  • any scalar or complex/compound data type must provide an appropriate default value that can be copied in depth (cloned)
  • the default value for a complex object type may be generated recursively using the default values of its fields

if you want to manually retrieve the default value for a given type, especially when using initializers only, you can use the following syntax:

<identifier> = default(<typespec>)

Common defaults

Below is a list of default value mappings for several JavaScript built-in types, which can be also used as plain initializers. Please note that the initializations to the default value are distinct even for the same data type, i.e. they are new copy-by-value assignments.

default(string)  -> ''
default(number)  -> 0
default(boolean) -> false
default(Object)  -> {}
default(Array)   -> []
default(Date)    -> new Date()
default(Map)     -> new Map()
default(Set)     -> new Set()
default(Symbol)  -> Symbol()

The 'null assignment'

for object-like data types, Descript® offers the concept of the neutral element, which is the read only/frozen reference of the default value of the type, having an additional hidden (symbol key) property, let’s call it isNull, set to true. This value gets used in the case of two special statements: the null assignment, and the null identity , the syntax for these two statements/expressions, which use behind the scenes the neutral element of the type, is:

<identifier> = void
<identifier> === void

Here, void is a keyword, and may be replaced with the less recommended keyword null.

Persistent types

Descript® builds and stores a collection of objects representing all user-defined data types of the current module/file and its dependency tree (imports). This collection will be present in the generated TypeScript/JavaScript code and at runtime. Each object of this collection is an instance of a class, let’s name it TypeObject, that has the properties of name and definition of a type, among its members.

The definition of a type can be either an object specifying the structure and the field type like in a TypeScript interface/JSON schema, or a string representing a type expression/operation like in a TypeScript Type alias.

To cope with more complex type operations, and to provide the alternative of specifying the default value, the syntax for the previously discussed type statements becomes:

<typedef>[ default = <object>]

Persistent definitions

Certain relevant source info found in entity definitions such as class details, enum namings, field validation etc., is no longer found in the runtime. There is a slight confusion between the efficiency of checking such info at frequent runtime operations like assignments, and the benefits of accessing it on demand when e.g. validating remote data. Descript® makes a policy of gradually ensuring the presence of all relevant source information when adopting the corresponding entity definitions as native keyword statements. In the rest of the cases, one should apply the policy of 'the least common denominator ', by writing the simplest JavaScript/TypeScript construct common to the most JavaScript dialects. The source-to-runtime relevant info policy is part of a larger concept called 'the program as a configuration '.

Keywords

Descript® tries to do minimal alterations to several JavaScript/TypeScript keyword statements in a way that conforms to Descript’s syntax, while working behind the scenes to keep the important information of these statements available in the running program.

In the code syntax hereafter, the square brackets denote optional content, while the angle brackets denote placeholders.

Variable declarations

var[ <type1>] <name1>[ = <init1>][, [<type2>] <name2>[ = <init2>]...]

the var keyword automatically maps to the let keyword in JavaScript, for the most cases. Here, <name1> is an identifier name, <type1> is a no-whitespace string denoting the variable type, <INIT1> is an initial value. Either the type, or the initial value are optional, but not both. If you want to specify an exact mapping, although not recommended, use the keyword vara for let and the keyword varb for the JavaScript var.

const[ <type1>] <name1>[ = <init1>][, [<type2>] <name2>[ = <init2>]...]

the const keyword is similar to and automatically maps to the JavaScript keyword const. all the component parts of the statement have the same meaning as in the previous var statement.

Please keep in mind that even if only the type of a variable is specified, the variable will be initialized with a value which is the default value of the type, as shown in the section 'Default value'.

Function definition

func[ <rettype>][ <fname>] ([[<type1> ]<name1>[ = <init1>][, [<type2>] <name2>[ = <init2>]...]])
    <body>
endfunc

The func keyword automatically maps to the JavaScript arrow function, except for the methods of a class/object where it maps to the function keyword. Here, <rettype> is the return type of the function which defaults to void, <fname> is the function name which is optional for function expressions, and <type1>, , etc. are the type, name and initial value of the formal parameters of the function obeying the same rules as in thevarstatement. Thesection of the function holds zero or more statements, including the return one, if necessary. The opening and closing parentheses are mandatory. For an exact mapping, although not recommended, use the keywordfuncato map to and arrow function, and the keywordfuncb` to map to a normal function. You are encouraged, though, to use the JavaScript arrow notation directly, for one-liner or simple function expressions, if avoiding the curly brackets.

Because the combination between a function signature and its body code is rather unique, for block/module/file level function definitions not prefixed by an assignment, the above syntax maps and translates to:

// TypeScript code
const <fname> = ([<name1>[: <type1>][ = <init1>][,  <name2>[: <type2>][ = <init2>]...]])[: <rettype>] => {
    <body>
}

Class definition

class <cname>[ EXTENDS <supname>][ <classmod>] as
   [<scopemod>:]
   [static ][const ]<typespec> <name1>[ = <init1>][, <name2>[ = <init2>]...]
    ...
    construct ([<paramlist>])[ : <supname>([<paramlist1>])][ : (<PROPINIT>)]
        <constructbody>
    endconstruct
    [static ]get <type1> <prop1> ()
        <getbody>
    endget
    [static ]set <prop1> (<type1> <name1>)
        <setbody>
    endset
    ...
    [static ]func[ <rettype>] <metname> ([<paramlist>])[ abstract]
        <metbody>
    endfunc
    ...
    static block
        <blockbody>
    endblock
    ...
endclass

The class keyword signals the beginning of a standalone class definition and maps to the JavaScript/TypeScript keyword with the same name. the syntax emulates the C++ style while observing the specific JavaScript/TypeScript features available for mapping. The placeholders are: <cname> is the class name, <supname> is the name of the optional parent class, <classmod> are optional class modifiers like the implements clause, <scopemod> is a scope access modifier such as private, protected, public, <propinit> is the C++ style constructor initializer list, <typespec> is the mandatory type of all the properties following on the same line, <paramlist> is the parameter list for a method with the same semantics and syntax as in the func keyword, <type1> and <name1> are the type and the name of a getter/setter property, and <rettype> and <metname> are the return type and the name of a method.

Inside a class definition, the following rules apply:

  • each property declaration is a list of items of the same type having a mandatory type at the beginning, the list being either single-line or having only one item and its initializer
  • the constructor construct accepts a C++ style initializer list and a parent constructor call, if necessary, with the initializer list enclosed in parentheses when it doesn’t end on the same line
  • an abstract/not-implemented method has the abstract keyword immediately after its parameter list and must have no body

classes and functions - Advanced

Descript® supports the following advanced features regarding functions and classes:

  • the async keyword in front of a function definition marks it as asynchronous, while the same result is rendered if the await keyword is detected inside its body
  • an asterisk in front of the function identifier in a function definition marks it as a generator, while the same result is rendered if the yield keyword is detected inside its body
  • the abstract keyword in front of a class definition marks it as abstract, while the same result is rendered if one of its methods is marked as abstract
  • the const keyword in front of a property list applies to all its items and is rendered at minimum as the readonly modifier in TypeScript, a more appropriate way being with hidden properties and getters for the given names
  • constant instance properties of a class are allowed to be re-initialized in the constructor’s initializer list as in C++
  • all parameters lists of the methods of a class, including the constructor, obey the same rules as in a function definition, with the direct consequence that always exists a default constructor that can be called with no arguments
  • a class definition is also a persistent type with an instance of the default constructor as its type default value, while one can still put the expression default = <object> after the endclass keyword, although not recommended
  • if the class modifiers expression <classmod>starts with the bound modifier, all the class methods will get implemented as arrow functions

Conditionals

if <expr> do
    <ifbody>
[else
    <elsebody>]
endif

the if keyword maps to the same JavaScript keyword, and starts a conditional block statement. If the <expr> condition evaluates to true, the statements from the <ifbody> are executed, otherwise the optional else branch holding the <elsebody> is executed. Feel free to use the JavaScript ternary operator ?...:… for simple conditional assignments, when possible.

switch <expr> do
case <val1>:
    <body1>
[next]
case <val2>:
    <body2>
...
[default:
    <defbody>]
endswitch

The switch keyword maps to the same JavaScript keyword, starting a multi-choice conditional block statement. Descript® uses the concept of implicit braking' i.e. you don’t need to put break in front of the next case. You can still chain two or more cases by putting the keyword next immediately before a case. Also, two consecutive case clauses with no body between them are automatically considered fall-through. The <expr> is the expression to be evaluated to matching one of the <val1>, <val2> etc. values/expression, and the corresponding <body1>, <body2> etc. is executed when a first match is found. The optional default branch with the <defbody> is executed if no match is found. While not needed at the end of a case, you can still use break for an early BREAK FROM A BRANCH.

Loops and blocks

for <init>, <cond, <expre>> do
    <body>
endfor

for[ all] <key> in <enumerable> do
    >body?
endfor

for[ await] <elem> of <iterable> do
    <body>
endfor

The three forms of the for keyword are similar to their JavaScript counterparts, marking the beginning of a controlled loop block statement.

The first form of for is the classical one, having three expressions as parameters, separated by commas. The <init> expression is executed once when the for statement is encountered, the <cond> expression is evaluated first and each time the loop is to be executed, and, if false, stops the looping, and the <expr> expression is executed after executing the statements in the <body> section, on each iteration. If one of these three expressions includes commas, the corresponding code fragment must be enclosed in parentheses. Omitting one of these expressions is permitted in the same way as in JavaScript, keeping the necessary commas for an unambiguous syntax.

The second form of the for keyword automatically maps to the JavaScript for...in loop, enumerating the property/member keys of an enumerable entity like object and its derivatives. In Descript®, this loop is filtered by default, enumerating only the object’s own property keys, but you can include the entire object’s prototype chain by putting the all keyword AFTER THE FOR. The <key> parameter is a new or existing variable that gets the current property key name, the <enumerable> is the object or object-like being traversed, and <body> includes the statements to be executed at each iteration.

The third form of the for keyword automatically maps to the JavaScript for...of loop, iterating through the elements of an array, array-like object or anything that implements an iterable protocol. If the await keyword is present after for, the iterable object is assumed of having asynchronous elements like async functions or promises. The placeholders are: <elem> is a new or existing variable that gets the element for the current index/step, <iterable> is the array, object or iterator to iterate over, and <body> holds the statements to execute at each loop iteration.

while <expr> do
    <body>
endwhile

repeat
    <body>
aslong <expr> endrepeat

The while keyword maps to the while... statement in JavaScript, whereas the repeat keyword maps to the do...while statement, both starting an uncounted loop block statement. The repeat form of the loop ensures at least one initial iteration, otherwise they being equivalent. The <expr> condition is evaluated on each iteration, determining the exit from the loop when is false, and the <body> statements are executed first and each time the loop is re-entered.

block
    <body>
endblock

the block keyword marks the beginning of a new lexical scope, mapping to a new pair of curly brackets in JavaScript, holding the same <body> content. In most cases, this statement is not required.

Exceptions

try
    <trybody>
catch[ (<except>)]
    <catchbody>
[finally
    <finbody>]
endtry

throw <expr>

The try keyword starts an exception catching block statement similar to the try...catch JavaScript statement. The <trybody> holds the statements that are watched for any exception, the <except> optional variable is the exception/error that is caught, the <catchbody> holds the statements that are executed after the exception occurs, and the optional <finbody> holds the statements that are executed anyway at the end of the try block.

The throw keyword marks the beginning of a non-block statement similar to the same keyword in JavaScript. The <expr> placeholder is the exception, error, or error-like object to be thrown, following the JavaScript specific error flow when not caught.

Enums and namespaces

enum <enumname>
    <name1>[ = <val1>],
    <name2>[ = <val2>][,
...]
endenum

The enum keyword is the same as the corresponding keyword in TypeScript, marking the beginning of a block statement. You can take advantage of the syntactical rules in Descript® and make this a single-line statement terminated by a new-line ending, when possible. The placeholders are: <enumname> is the enumeration name, >name1?, <val1> etc. are the keys and the optional numeric or string initializeers.

namespace <naming>
    <body>
endnamespace

The namespace keyword marks the beginning of a block statement similar to that in TypeScript. The <naming> is the namespace designation, while the <body> holds the code that is appended to the given namespace. This construct should not be used instead of ES modules, but may be useful for organizing large collections of hierarchical code such as libraries.

Other statements

Generally speaking, Descript® accepts most of the JavaScript statements and several TypeScript ones in a form suitable to its syntax, i.e. no or least semicolons and a new line as a statement separator. Examples of such statements that can be used unchanged, are within the following categories:

  • the module import and export statements, with all their variants
  • the flow breaking statements like break, continue, ``return, or yield, preferably each on its own line
  • certain TypeScript statements like enum, beneficial for your code, as long as they aren’t available natively

Other syntax

When not using the Descript® syntax, there are no restrictions of writing your regular TypeScript or JavaScript code depending on the target, taking into account the previously mentioned principle that any newly created variable must point to an appropriate non-null content.

Operators

All JavaScript operators are available for using, including: arithmetical, logical, bitwise, member access with dots or brackets, special ones like new, delete, typeof, instanceof etc. Take care though, not to use an unintentional delete on an object member and later expect a structure conformant to the original type.

Expressions

All JavaScript expressions conforming to the modern coding practices are accepted. They include: higher-order methods, anonymous functions, closures, use of the special keywords this and super etc. Pay attention though, not to assign or pass the undefined or null result of an expression to a variable supposed to be substantial. If you temporarily need to signal an object as being in a null state, please refer to the section about the 'null assignment'.

Destructuring and the rest operator

There are two scenarios where new variables are created in the context of destructuring: identifier bindings in variable declarations, and parameter bindings in function definitions. In both scenarios the destructuring syntax is the same and involves the following steps: creation of local variables or local function parameters, assignment by position for array destructuring and by property name for object destructuring, optional renaming of named properties, optional assignment of default values for variables not assigned or set to undefined. Although in TypeScript the type annotations are not available when destructuring, in Descript® either the types or the default values are required for all destructured variables excluding the rest property. Specifying the type in front of a group of variables contained inside array or object notations distributes it to those not having a type, as in 'type grouping' paragraph.

In fact, the language must ensure that each variable receives a non-null content, so it’s recommended to always specify default values especially for multi-level destructuring.

// array type grouping
const <type> [a, b, c] = ...
// works the same as
const [a = default(<type>), b = default(<type>), c= default(<type>)] = ...

// tuple types
const [<type1> a, <type2> b, <type3> c] = ...
// works the same as
const [a = default(<type1>), b = default(<type2>), c = default(<type3>)] = ...

If the rest operator/notation ... is applied to the last element/property in a variable list, this rest variable will always have the non-null type of Array or Object respectively. Also, if a function definition parameter list ends with a rest parameter, this parameter will have the non-null type of Array.

File types

The source files in Descript® are called DES files, and have by default the .des extension. This extension is also assumed when using the import statement, if not specified.

Symbolic keywords

A set of symbols can be created and used instead of keywords, one for each keyword in principle. A symbol is a glyph or an art font suggestive for the given keyword, which may be asymmetrical left-to-right so that its mirror on the vertical axis can be used for the pairing ending keyword, when necessary. A crude example would be replacing the func keyword with a f~( like symbol. The sauce code using symbolic keywords can be flipped from LTR to RTL reading without losing its semantics.

The mission

Descript’s mission is to make it easiest to learn and write coding as a way of thinking and communicating universally.