Programming language and environment

Things to support from the start

These aspects should be implemented from the start for a programming language. For some of them, we have some insight on how to implement that feature more easily than usual.

Key insight: take program manipulation concepts that are usually external to the language, and integrate them into the language, using first-class environments, first-class continuations, laziness (for macros) and syntax quotations (for macros).

Feature Insight
evaluator
serialization of all run-time values, and of the entire program state language design (entire state representable by a term)
diff tool (e.g. sexp-diff for sexps), with JS or server-side implementation for to highlight diffs in online versionned repositories generic row map in metalanguage
debugger (with domain-specific extensions http://scg.unibe.ch/research/moldabledebugger) defunctionalize(cps(evaluator)) + explicit env + continuations to make the stack explicit (+ lazy on program to pause before evaluating a term?)
instrumentation for performance / profiler use debugger's step-by-step or sampling via GC API or instrumentation by injecting code (via macro)
code coverage, with on-line web interface to display of the code coverage results + doc-coverage done via instrumentation
communicate with native libraries in-place serialization / expressive type system
multicore (can be simple "parallel_for" / "parallel_map" or explicit thread management) implementation via native library
garbage collection ~25 lines of code / reference counting
lexer, parser, syntax highlighting, projectional editor Christian for 1 & 2. Have a good GUI library for 3.
type inference / propagation ! unidirectional propagation, domain-specific type systems
typechecking ! interactively explore type errors: better than msgs
simplification passes Nanopass
compilation to JS don't rely on single-architecture native libraries
compilation to native executables no need to optimize at the beginning
module system ! row polymorphism
package system purely functional package management (Nix)
package repository with browser (sort & filter by criteria) web & social stuff, use compilation to JS
* e-mail you when a package you maintain is broken on the "dev" branch
* e-mail you when a dependency of one of your packages has a security vulnerability, or has a breaking update. Show status to reward quality.
centralized online documentation repository with clickable identifiers in code fragments and cross-references good resolution of ids (see refactoring)
* plus search engine to find functions by their type, description, module that provides them etc. (hoogle) use compilation to JS + unification algo
* search engine for error messages, translatable error messages error codes (Error FOO1234: …) + use translation library from the start + interactive error messages (expand info, go to documentation, …) instead of plain strings
browse source code with hyperlinks and diff between versions good resolution of ids (see refactoring)
literate programming explicit env, macro-like facilities
macros laziness + quote syntax + inlining
API for IDE explicit env, refactoring = expansion of a single macro
* Go to definition
* rename across files
* rename files (modules) themselves
* other transformations for occurrences of an identifier (eta-expansion etc.)
* other refactoring operations
* display compiler warnings, lint info, type info, static analysis info annotations produced by macro-like things
indenter (indents but does not change newlines), possibly (likely?) customizable ! find a good framework to express indentation rules
Policy for package API evolution & security vulnerability patching ! Run tests of previous version to see that they all work but may introduce warnings; IDE support for deprecating features and bumping the version number; provide a rewriting: if the rewriting validates a proof that the behaviour did not change it can be applied automatically, else manually or warning because the actual use follows an undesired pattern
pretty-printer (indents and inserts newlines to try to fit within a certain width), possibly (likely?) customizable ! same as above
* graphical / annotated pretty-printer good GUI framework
queries on the source code (find functions with more than X lines, show dependency graph, …) code inspection via macro-like things
every IDE, runtime and language feature available in a web interface (trylanguagefoo.io demo for new users and playground) use compilation to JS + good GUI framework
compilation should produce a single-file output enables purely functional package management & pure build system
extraction of the dependencies of a file first-class environment helps
package management: should be easy to export the state to a single file, to make it easy to create packages in a third-party package manager. single-file output + dependencies extraction
static analysis just make sure there's an API for that from the start
linter just make sure there's an API for that from the start
"modes": build, doc, test, runtime (for dependencies, tree-shaking etc.) ! think about it, relates to packages and builds

Parser

Notation "p => e" := (mk_pattern p e) (p in scope pattern, e in scope expression)
Notation "p | p'" := (combine_patterns p p') (in scope match_cases)
Notation "match x with cs end" := (mk_match x cs) (cs in scope match_cases)

Notation "p => e" := (mk_pattern p e) (p in scope pattern, e in scope expression)
Notation "p | .. | p''" := (combine_patterns p .. (combine_patterns p' p'') ..) (in scope match_cases)
Notation "match x with cs end" := (mk_match x cs) (cs in scope match_cases)

A way to express the notation

match x
  case p₁ => e₁
  …
  case pn => en
end

and the notation:

(case p₁ => e₁
 …
 case pn => en)

If:

Notation ""if" a "then" b "else" c" (c bounded-by-start-and-end-kws)
Notation ""if" a "then" b"          (b bounded-by-start-and-end-kws)

allowed uses:

if true then f 1 2 3 else (g 4 5)
if true then f 1 2 3 else (g 4 5)

allowed if the precedence of function calls and arithmetic comparable in some direction (less than? or should it be greater-than?) with the if:

(if true then f 1 2 3 else g 4 5)       (* delimiter at the start of the if indicates that it's ± safe to parse till the closing paren, might be a bad idea *)

forbidden uses:

if true then f 1 2 3 else g 4 5         (* could be followed with other things *)
if true then f 1 2 3                    (* could be followed with other things *)
(3 + if true then f 1 2 3 else g 4 5)   (* could parse as (3 + (if true then f 1 2 3 else (g 4)) 5) or (3 + (if true then f 1 2 3 else (g 4 5)))

Nested pairs in the left:

Notation "( x , y .. , z )" => (pair .. (pair x y) .. z)
Notation "( x , ... , z )" => (pair .. x .. z)

Two successive keywords:

Notation ""let" "rec" a ":=" b "in" c => (letrec a b c)

Custom notations for strings (escaping, $var substitution, @{code} substitution, …)

Relative precedences

Custom top-level parser: e.g. for literate programming, custom syntax (ala prolog, ala pascal, ala scheme, ala C).

Loading a library can modify the parser. What about let open … in …?

Unparsing (pretty-printing)

Is it possible to rename the lexer tokens used by a notation? E.g. if a module provides the notation match x with cs end, it could be imported while renaming match to switch, with to in and end to done. If this throws an error at import-time because it conflicts with existing uses of in that's fine.

Preferably, there would be a conservative way to know for sure that the notations Foo and Bar from modules A and B won't interact with each other, as long as some (possibly stringent) conditions are met, e.g.

The goal is to know, when modifying a notation in a library, if this is going to be a significant breaking change (another alternative would be to have IDE support to do the alpha-renaming in a non-ambiguous way).

Review of Coq as a language

issues with coq

cool stuff in coq:

Review of Agda as a language

TODO.

Review of Idris as a language

TODO.

Review of Epigram as a language

TODO.

Review of other_language as a language

TODO.