ideas-computer-jasper-whyJasper

Difference between revision 32 and current revision

No diff available.

note that none of this has been implemented yet, and the design is still in flux! many of these items, although written as facts, are in fact wishlist items!

I am just writing down ideas. I have many pages of notes on things i may or may not want to put into Jasper.

At this point, the design is unfinished; there is no coherent concept of a language called 'Jasper', just a bunch of ideas towards such a proposal. There is no timeframe to actually implement this, and it most likely will never get finished.

To be clear, i repeat myself: there is no such thing as Jasper. Jasper has neither been designed nor implemented. These notes about 'Jasper' contain many conflicting proposals.

This page is mainly a collection of feature 'todos' for me, that is, an aid in designing a programming language, or an answer to the question, 'Why do i want to write Jasper?'. But the reasons for writing it are not necessarily reasons for someone to decide how to use it. See also Rosetta language comparison methodology.

Intro

Jasper is a readable programming language focused on massive concurrency. It has a single fundamental data structure. It is a high-level, programmable programming language. It provides convenient constructs for safety and error handling. We value great libraries, and both the language and the community process are designed to encourage this.

Jasper is a multi-paradigm language with higher-order polymorphic gradual typing and automatic reference-counting. It has elements of the lazy functional, imperative, logic, and object-oriented paradigms. It is open source with a permissive license.

Jasper strives to support tooling and interoperability.

Jasper is a general purpose language that particularly targets the application domains of:

Some downsides of Jasper are:

Readability

Jasper's number one concern is to be readable. Readability means that a Jasper programmer can quickly understand someone else's source code. Readability implies simplicity (the ease of understanding and remembering the language) and expressivity (the ability to write programs the way you think of them).

todo

Jasper strives to have 'scannable' syntax; meaning that your eye can quickly scan through code looking for where a certain thing occurs.

todo

Also, a word about simplicity, size, and learnability. Jasper is a simple, small language which is easy to remember. However, although the language is small, it has a large standard library, so in order to become fluent in Jasper idioms and read others' code there is a bit to learn. Jasper is focused on being easy to remember, but not necessarily easy to learn; what I mean is that it may take you more than a few days to grok it, but once groked, you should be able to work on it on weekends every now and then without having to spend a lot of time getting back up to speed.

todo

relation to concise: we value conciseness but we see this as only a means to the ends of expressivity and readability. Insofar as 'concise' just means 'i want to write it the way i think of it', that's what we're calling expressiveness. Insofar as lack of boilerplate makes it easier to see what code is doing, we value reduction of boilerplate. Insofar as making programs shorter makes them easier to quickly understand, we value making them shorter. But insofar as 'concise' means 'Making programs really short by inventing non-intuitive abstract operators that must be 'unpacked' by the reader to understand the program', we disagree. We would rather have you write more code if that will help someone else understand it quicker.

(note: non-intuitive abstract operators are fine with us if their usefulness is broad enough to make it worthwhile for every advanced user of the language to learn them; but not if they are application domain specific. But we still don't want to add too many non-intuitive abstract operators to the language, because that impairs our other goal of simplicity.).

small

todo

todo

relation to powerful: if by 'powerful', it is meant, 'enough features so that i can do what i want without writing much new code', then we are focused not so much on providing every desirable feature within the language, but rather upon making the language expressive enough so that it's possible to write a library for that feature that allows source code using it to read naturally.

todo mechanistic concepts are simpler than others

Massive concurrency

Our brain's neurons are individually slower than computer CPUs, but it makes up for this by having a lot of them. Moore's Law isn't increasing CPU clock speeds at an exponential rate anymore, but instead it is giving us the possibility of many processors working in parallel. Together, these show that it is possible to do interesting things with massive concurrency, if only we knew how to write software that could use it. Jasper is a platform for experimenting with ways of writing massively concurrent software. todo shorten this or throw this out.

todo

todo data parallelism

todo purely functional code with local state

todo transactional memory

One powerful data structure

When many operations are provided for a few pervasive data structures, it becomes easy to compose functionality. Python has lists and dicts. Haskell has lists. Can we do better? Jasper has one fundamental data structure, the Jasper graph (note: in addition to this one composite structuring element, there there are still multiple atomic data types, such as integers, etc). Watch a few computer science lectures and it quickly becomes clear that much of computer science can be expressed with graphs. Lists, associative arrays, matrixes, dataframes, relations, partial orders, and more are all special cases of Jasper graphs.

In pursuit of as much generality as possible, Jasper's graphs are directed, labeled, reified, hyper, multi graphs.

Directed

labeled

reified (both edges and the entire graph can be referenced like 'nodes')

hyper

multi

views

binding

boundaries

todo

High-level, flexible

Jasper works at a high level of abstraction. This means that you can write abstract code which is flexible enough to be adapted to various uses. It also means that you can express what you want a program to do, and Jasper will handle some implementation details for you.

todo

todo

A programmable programming language

What's all this you hear from those Lisp guys about a style of programming where first you augment the programming language to suit your domain, then you write a program in your new language? We'd like to do that too.

And what's all this about a small language, a gem-like thing of perfect beauty, in which can be written a (meta-circular) interpreter for itself in only a few pages? Around which a larger, more practical language can be built? That's pretty cool, also.

As a bonus, the effort to find a set of primitives that are good for building a larger language helps us find powerful primitives, and a self-hosting language built on a small core is easier to port. Furthermore, if the language is small enough, and the abstractions are powerful enough to allow it to be implemented concisely, then the language implementation will be readable by ordinary mortals (sans a million optimizations, but we can keep them in a separate module).

todo list meta-programming features

However, we are aware that use of meta-programming features can make source code hard for others to read. Jasper provides an (approximate) ladder of meta-programming mechanisms, and encourages the use of the less powerful mechanisms when possible (temperance will also allow us to optimize your code more). The most powerful metaprogramming mechanisms are only for use when all else fails.

Jasper itself is made of three parts; Jasper Core; a language written in Jasper Core using metaprogramming; and a large standard library of language-like constructs.

Safety and error handling

Mature code contains a lot of error handling, and programmers spend a lot of time debugging. Therefore, a primary concern of Jasper is to reduce bugs (safety) and to provide convenient, readable mechanisms for handling errors.

todo

Libraries

Much of the practical utility of a language comes from its libraries.

Jasper attempts to provide the power of meta-programming while avoiding the curse of Lisp (namely that libraries in a very powerful language have trouble creating enough 'gravity' to attract contributors).

todo

multi-paradigm

todo

type system

todo

Gradual typing

success typing

can use assertions to override/escape type system

memory management

todo

other properties

todo

concise

expressive

modular

tooling

interop

application domains

todo http://en.wikipedia.org/wiki/Scala_%28programming_language%29 has a nice list of individual features, most of which we have. also, add these to PL book constructs list.

Features that achieve the above goals

Readability

(from concise)

One data structure

simple, programmable programming language

High-level, flexible

(from flexibility)

(from modularity)

Safety and error handling

Libraries and Communal Gravity

Massive concurrency

good tooling, implementation, ecosystem, interop

todo: cp everything above '== Syntax ==', above, into this table

Data

Jasper is built upon a single powerful data structure, the Jasper network (net).

A single powerful data structure

Lisp is a homeoiconic language built upon lists. Jasper is a homeoiconic language build upon networks (labeled directed graphs).

Type attributes, not different data types, for efficiency

Semantically, a linked list, a doubly-linked list, an unboxed list (vector), and a hash table with natural number keys are all similar; they are all lists of things indexed by natural numbers, all of which support sequential access, random access, appending, insertion, and deletion. The differences are the space and time complexity of these various operations. In Jasper, these things all look the same; if you want to choose one or the other for efficiency reasons, you use type attributes (a kind of annotation) to specify.

Uniform treatment of array lookup, function application, and structure lookup

In Jasper, the following two operations look the same: (a) looking up the third element of the array in variable "x", and (b) applying the function in the variable "x" to the number 3 and getting the result. This allows library functions to present a simple interface that can be thought of in terms of arrays, while allowing the caller to use arbitrary objects in place of those arrays.

Furthermore, fields on structures are treated the same way. This makes it easy to replace a structure that formerly used simple fields with one that uses intelligent getters and setters under the hood (this supports the so-called http://en.wikipedia.org/wiki/Uniform_access_principle ).

Bias towards immutability

Data operations in Jasper are, for the most part, expressed as functions on immutable values, rather than as changes to mutable data. Those that are not are clearly demarcated.

However, there is an exception. We freely allow 'local mutation', that is, mutation that takes the form of assigning a value to a symbol within a scope and then later reassigning a different value to that same symbol within the same scope. This kind of mutation could in theory be eliminated by renaming every mention of the variable after the reassignment (and doing some copying in the case of multiple branches, e.g. if the reassignment occurred in only one branch of an 'if' statement). We feel that this is useful to avoid having to create throwaway names for intermediate variables.

We feel that local mutation isn't bad; the bad (confusing) stuff is when you have aliasing of references, that is, when a change to the value of one variable 'magically' causes a change to a different variable (especially when the two variables are located in two different scopes, neither of which is an ancestor of the other).

Uniform treatment of metadata

Jasper has a system to allow various frameworks to attach their metadata to values.

Powerful graph abstractions

The Jasper nets are labeled, directed, multi, hyper, reified graphs. Jasper networks are:

Nodes in Jasper nets can be arbitrary functions.

Each node in a net can used as a simple array or lookup table. However, Jasper supports more powerful idioms that regard the network in its totality, rather than each node individually. For example:

Nets can be used to represent regular multidimensional labeled arrays, similar to R dataframes.

Boundaries

A net boundary is a border that cuts through a set of edges in the graph.

Boundaries in code are used to represent atomic operations, exception catching domains, etc.

Patterns

Net patterns are a matching language that generalize regular expressions and database queries to nets. Net patterns are first-class objects.

Views

A view is a different set of labels and edges associated with the same nodes. Views allow the same data to be presented in different ways to different functions operating upon it. For example, a dictionary could be presented as a list of key, value pairs, and mutations on this list could alter the dictionary.

A mutation to data in one view can affect the same data in other views. When one view is a projection of another, syntax is provided to specify the 'lineage' of data so that metadata attached to a node N1 in another view remains attached to the correct node(s) if N1 is mutated by way of replacing it with a new node.

Functions are first-class objects

Since network nodes can be functions as well as static lookup tables, they can be passed around as data.

.set protocol

.apply protocol

Typed streams/pipes/message queues

todo

Control flow

Laziness

Jasper has a lazy evaluation strategy; values aren't evaluated until they are needed. This allows for separation between definition of data structures in the abstract, and the control flow used to traverse them. For example, if you are writing a chess-playing program, you can represent the entire tree of possible chess board states in a data structure, and worry about how and how far you traverse this unrealized data structure elsewhere.

A useful special case is infinite data structures; for example, you can have an array which contains all prime numbers; unless you try to traverse this array arbitrarily far, this does not cause your program to hang because thhe unaccess members of the infinite array are never computed.

Reasoning about memory

In other lazy languages (e.g. Haskell), it can be hard to reason about and memory leaks (e.g. "space leaks"), or to discover them via profiling. Jasper makes this easier.

In addition to providing operators like Haskell's seq and deepseq, which forces strictness in a top-down manner, Jasper allows you to mark data values as eager; a function fed eager inputs will eagerly evaluate them. This forces strictness in a bottom-up manner.

Jasper presents the programmer with abstractions like 'fold'. The choice between functions corresponding to Haskell's foldl, foldl', foldr, foldr' is made by the compiler based on strictness analysis of the arguments. The sort of analysis discussion on this page ( http://www.haskell.org/haskellwiki/Stack_overflow ) is done by the compiler.

Jasper automatically converts 'almost tail recursive' functions with only associative operations preventing them from being tail recursive, to tail recursive accumulating ones.

TODO

Tail call optimization

Jasper can eliminate recursive tail calls, allowing efficient deeply nested recursion.

Multiple entry, exit points, multiple stacks

Jasper allows functions to have multiple entry points (this is sort of like a object with multiple methods that is only executed once). The function can synchronize on conditions between these entry points before executing. The notation is uniform with message handling (see below).

State management

Referential transparency by default

For the most part, Jasper "long-distance" operations are referentially transparent. Those that are not are clearly demarcated, allowing the programmer to steer clear of unwanted side effects and unexpected shared state.

Compiler inference of referential transparency

You can ask the compiler whether any function is referentially transparent. This is accomplished in a similar way to Haskell's use of monads to type non-referentially transparent functions as 'tainted', but it is done implicitly without the need for the programmer to worry about those types or to manually change a bunch of type annotations if you decide to make something non-referentially transparent later.

Escape hatch for debugging

You can do non-referentially transparent operations without tainting for the purpose of debugging and profiling, in a manner similar to Haskell's unsafeIO.

Escape hatch for caching

You can do seemingly non-refentially transparent things without tainting if you promise the compiler that their behavior is actually referentially transparent.

Lexical block scoping + object scope

Variable scope is simply defined by the block of code that they are present in, except that there is also a way to refer to the "object" of which a function is a part (a "method" in other languages).

Closures and References

Closures and References are supported but any variable containing a reference or a structure containing a reference are clearly distinguished from values with sigils.

Semiglobals

Syntactic sugar for passing objects that mimic dynamically scoped variables.

Message handling

Jasper provides a powerful, uniform, concurrency-friendly mechanism for messages to propagate and be handled.

This is used for event-driven programming, exception handling, dispatch, and parallelization.

Concurrency

Jasper has a zoo of powerful constructs for correct, concurrent programming.

todo (see zoo in [1])

Error handling

Error handling for pure functions is through Maybe (option) types. Maybe types can be subclassed to give more information on the type of error when a Nothing is returned.

Error handling for mutation is thru exceptions, however Jasper provides a concise operator to convert a return value from a function that might throw an exception into one that returns a Maybe, and vice versa.

scope(fail) and scope(end)

Like D's, these allow you to place code that undoes side effects in the event of an error right after the code creating the side effect.

transactions and .__undo attribute

Jasper provides a way for side-effectful code to specify how these side-effects can be reversed, if they can be at all. Jasper can use this to allow the programmer to create transactions.

RAII/context managers

Like C++ RAII or Python 'with' statements, you can ensure that resources are freed by use of an object protocol.

If the caller uses a 'with' (todo find a different name), this occurs as the stack is unwound, otherwise it occurs when the object is garbage collected (unless there is a reference cycle of objects which reference each other in their cleanup routine, in which case a runtime warning is generated).

(todo: if the protocol mixes stuff like Python __del__ and Python context mananger __exit__, then what to do if an object in a 'with' goes out of scope but participates in a reference cycle of other objects with finalizers?)

Modularization

Component programming system

Jasper has a powerful module system and a built-in runtime component system with facilities for directories of components, dependencies and capabilities, configuration, parameterization of types, declaration and binding to extension points, typed messaging, and event handling.

Inheritance and composition

Jasper allows you to flexibly inherit from or to compose new code with old.

Encapsulation

Jasper allows you to encapsulate data structure definitions with operations to act on those structures.

Type system

In Jasper, the philosophy is that the type system is your servant, not your master. We see static typing as a way to allow the compiler to prove theorems about your program. These theorems are useful for (a) autocompletion in IDEs, (b) preventing bugs, and (c) optimizing execution.

Optional static typing

Because there is a cost (the programmer must do some extra work to help the compiler prove the theorems), static typing is optional; by default, all variables are dynamically typed, and you can enable static typing for everything or for any subset of variables that you choose.

Type inference

To save you time writing type annotations, Jasper can infer some of them.

Powerful yet comprehensible

The type system is powerful and extensible. We support generics. We support type attributes such as 'immutable' and 'unique' that constrain, not the structure of data, but rather how it can be accessed. We allow the user to define custom attributes of this sort themselves. The type system is extensible enough that you can use it to ensure the correctness of all sorts of things, using techniques such as loop invariants and programming-by-contract.

However, the type system's power is limited in order to make code easier to understand.

One important principal is that, when reading code, complex reasoning about static type inference should not be necessary to figure out what the code does.

For example, in many ways Jasper's type system is less powerful than Haskell's; we limit the power of the type system to (combine type inference with polymorphism in order to do compile-type computations that alter or determine the semantics of code), e.g. stuff like http://stackoverflow.com/questions/3467279/how-to-create-a-polyvariadic-haskell-function .

Although the type system allows you to express complex statically-checked constraints on semantics, for the most part this power can only be used to doublecheck the semantics that are explicitly expressed in code, rather than to resolve semantics that the rest of the code leaves ambiguous.

Everything is an interface

Although Jasper has inheritance, the type system will never require you to inherit from anything or to use a certain implementation of a data type; everything is an interface.

Interfaces/typeclasses/attributes/structural typing, not principal types

In Jasper, you don't think that a value IS a type, for example "3 is an Int". Rather, you think that value X has a type attribute, for example, "3 has the property of conforming to the Int interface". "3" might have other properties as well, for example, it might conform to the Num interface, and it might conform to the Serializable interface. The Serializable type attribute is no more fundamental to 3 than the Int type attribute (at least as far as the type system is concerned).

You don't have to inherit from another implementation of something in order to make a replacement for it; you just have to implement the appropriate interface.

If you want to make something to replace a duck, you don't have to convince the compiler that it IS a duck; you just have to make something that walks like a duck and quacks like a duck.

Intersection types

Uniform notation for typing, net patterns, constraint satisfaction, and logic programming

Uniform notation for operations on types and operations on values

For example, you can look at the type List of homogeneous lists to be a function that takes a type value (the type of the elements in the list) and returns a type value (the type of a list of those elements). The notation for this sort of thing is the same as for ordinary functions.

Assumptions

The type checker is your servant, not your master. If you want some amount of typechecking or static assertion verification on a variable or module, but there is some piece of code for which you don't want to bother right now to write a proof that it does what it should, you can instruct the type checker to simply assume the result that you want.

Embedded proof checker

Jasper provides a Coq-ish decidable theorem prover with customizable tactics to allow you to express and prove difficult assertions about your code.

I am NOT suggesting that you will have to write a proof in order to get your program to type check; the proof checker is provided so that you can (a) opt to encode complex invariants that the compiler verifies, with your help; (b) extend and customize the type system.

Generics

Union types

Serialization

Jasper has facilities to permit convenient serialization of any type.

Syntax

Jasper has a simple, near-homoiconic syntax with an emphasis on conciseness and readability.

Jasper's lexical syntax is based on regular experssions, and its parse syntax is LL(1) and does not require a symbol table, making it easy to parse.

Simple, near-homoiconic syntax

Most of Jasper's syntax is for grouping (and quotation, which is a form of grouping).

Concise

todo

Jasper was designed to minimize the necessity for delimiters. For example, a function call that in many language would be written "f(x)" is just "f x" in Jasper.

Readable

Jasper has syntax for assignment to an element of an array, a common operation that some languages lack concise, readable syntax for.

Jasper does not permit custom operator precedence because that would require you to to look up operator definitions before you can parse code that you are reading.

Footnotes

Footnotes are a convention that allow you to present "the main part" of a function uninterrupted, and then to handle error checking, logging, variadic argument checking, parallelism annotations, other annotations, etc in the footnotes.

Keyword and optional function arguments

You can pass in arguments to a function by keyword instead of by position. Keyword arguments can be optional.

Optional significant whitespace

But not significant indentation.

In Jasper, the presence or absence of (a) space in between words, (b) newlines, (c) an empty line (a line with no non-whitespace characters) are significant, but the amount of these (indentation level, etc) is not. Any code can also be written in a "one-liner" without whitespace.

Easy partial application

If a function takes two arguments and you give it one argument, the result is a partially applied function.

Multiple, labeled, optional return values

Jasper return values mirror function arguments; they can be many of them, they can be labeled by keywords, and they can be optional.

Anonymous functions

Flexible operator application

You can create vector variables such that when you apply ordinary scalar operations to them, they are applied to each item in the vector, without having to extend the definitions of each operation to be able to handle vectors. There is a generic way of extending operators to act in ways such as this.

You can represent mathematical 'Del' in Jasper, and Del(f) = gradient of f, dot(Del, v) = divergence of v, cross(Del, v) = curl of v.

Notation for 'metavariable'

In statistics, some operations apply to values (and expressions act as if each random variable in the expression had been instantiated to a particular value), and others apply to expressions and care about the random variables in them. For example, if X is a random variable, "X + 3" is the former, but "var[X]" is the latter; if y is a 'normal' (non-random) variable, and Y is a random variable, then when simplifying, var[X + y] is treated differently from var[X + Y], because in the latter case we have to know if Y is correlated to X.

Jasper uses ?x to mark x as a 'metavariable', which means different things in different contexts; in the context of statistics, a metavariable is a random variable. Functions which act differently when given expressions with metavariables ar distinguished with a ? suffix; so we have mean? and var?.

Operations

Operator overloading

However, every operator must also have an alphanumeric function name, so you can use those if you don't like line noise.

Metaprogramming

Jasper's approach to metaprogramming is to provide a ladder of less- to more- powerful metaprogramming constructs. Programmers are encouraged to stick to the less powerful constructs when possible to promote readability, but the more powerful ones are there in case you need them.

Annotations

Source filters

Syntax rules

Delimited continuations

Jasper supports first-class delimited continuations, which means essentially a first-class abstraction of the state of part of the stack.

First-class stacks

Monads

todo

Macros

Hygenic macros are applied to source code after Jasper parsing but before anything else.

Optionally, the hygenicity can be weakened with with inner keyword/keypatterns, that allow the macro to access the actual string naming a symbol, allowing the creation of frameworks similar to Ruby on Rails, which associates symbols to database tables based on their name. Such symbols have sigils and/or capitalization to allow readers to recognize that their name is important.

Character-level macros

These allow you to write custom handlers for strings within the source code that will be exempted from Jasper parsing. For example, regexes are implemented using these. These can also be used to intermix foreign language source code with a Jasper program.

todo: list the other metaprogramming facilities

Tools and interoperability

Standardized, language-level support for advanced IDEs

The Jasper executable has an API that provides services for IDEs, for example, online parsing, online type inference, querying the type attributes of an instance of a token, querying for symbols meeting certain criteria, autocompletion, querying potential exceptions thrown by a function, and more.

Standardized, language-level support for documentation markup

Jasper has a standard notation for documentation markup.

Interoperability with popular languages and platforms

Out of the box, Jasper can call, be called by, and pass data to and from various popular languages. Jasper semantics and data structures are available from other languages via a standalone library. Jasper is available within various host platforms, such as JVM and .Net.

Low-level operations

Like C and Rust, Jasper can express low-level concepts, allowing it to interoperate with other languages.

Jasper can read and write to memory locations, and Jasper programmers can create data structures which specify their exact layout in memory. Jasper programmers can manually allocate and deallocate memory, and can perform pointer arithmetic.

Safe memory access

An illegal memory access produces a Nothing or an exception, not a segfault (unless the programmer turns off this checking for the sake of speed).

Lightweight threads

In the tradition of Erlang and Go, Jasper manages lightweight threads and prevents starvation.

Robustness

Erlang-ish interthread robustness facilities are provided.

Memory managed by default

By default, Jasper takes care of memory management, but you can opt to take control yourself if you need to.

Standardized tool for formatting convention

jasperfmt

Copy-on-write

Copy-on-write (COW) makes immutable value semantics efficient.

Self-hosting canonical implementation

Jasper is written in Jasper.

Portable

The Jasper implementation uses its own metaprogramming facilities to bootstrap itself off of a subset of the language, Jasper Core. This means that in order to port Jasper, all you have to do is to implement Jasper Core on your new platform.

Sandboxing

Jasper supports execution of untrusted code with limited capabilities. (note: while this is a design goal of Jasper, it is likely that the initial Jasper implmentations will have unintentional flaws, and so at least initially the sandboxing should not be trusted for high-value use cases).

Modular compilation toolchain

You can alter and extend Jasper by writing your own modules to be used in the compiler.

Dynamic changing of program; also, code auto-reloading

To allow you to experiment with a running program in the interpreter without stopping, recompiling, rerunning, and getting back to the state you were in, the Jasper interpreter allows you to dynamically inspect and alter the functions in memory during execution.

To allow you to edit source code files and re-run the program without manually giving the compile command, the Jasper interpreter will by default recompile changed source code dependencies when told to execute Jasper source.

Optional static binaries

A Jasper program can optionally be compiled into a static binary that includes all dependencies, making it easier to distribute single binary to production.

Package manager

Package manager that knowns about dependencies, signatures, volume of documentation, and canonicalness. The package mananger will almost never get 'stuck' in a state where it cannot install required dependencies. The package manager can get packages from the local file system, from a remote git project, or from a Jasper package website.

Governance process for canonicalization

A governance process that selects a subset of libraries as more or less canonical, yet not so canonical that they are included in the distribution.

Permissive license

Jasper is licensed under the permissive MIT/X11 license.

Brain-like paradigm

One motivation for Jasper is simply to make a useful programming language. Another motivation is to create a programming language in which it is easy to program in a paradigm which is my best guess for how the brain works. This should be useful because we know that the brain is capable of useful computation, and also in order to assist the cognitive studies students among us in gaining hands-on intuition about how the brain might compute.

Some tentative properties of this 'Jasper/brain' paradigm are:

Safety

No-crash by default

By default, Jasper does not do anything that could cause a crash (SEGFAULT), such as dereferencing arbitrary pointers, or accessing an array without bounds checking. However, the confident programmer can turn this off for speed.

Programming in the large

Access modifiers

Jasper contains a way for you to differentiate between a public interface and private implementation details, so that you will not break downstream programs when you change private implementation details.

todo rly?

Standard library

Jasper has a great standard library.

Collections

Jasper has a well-designed library of collections.

They include:

Many of these can be treated as simply graphs; their implementation is just an implementation detail.

Relations

Jasper can operate on relations.

Partial orders

Jasper can operate on partial orders.

Haskell prelude

Jasper's library has many of the functions in the Haskell prelude.

Integers and sequences

The operations of getting the length of a sequence and of generating a range of integers (or floating point or other numbers) has quite concise syntax.

Mathematical numbers

The mathematical integers, and multiple/arbitrary-precision arithmetic, are primary in Jasper; fixed-width number representations are secondary.

---

By niche / comparison to other languages

strong at lazy purely functional like Haskell, but easy to read like Python

conducive to macros like Lisp, but communal gravity like Python (and many other languages)

like Lisp, but based on labeled graphs (keyword arguments) rather than lists (positional arguments) (and more focus on readability; and slightly higher-level)

shell scripting: good for one-liners like Perl, but easy to read like Python

good for numerical computation like Python (and maybe but with less impedence mismatch between lists/numpy arrays and between method chaining and function call chaining) and Octave (but general-purpose language)

small-ish like (roots of) Lisp, Scheme, Nock, C, Lua

massively concurrent

robust concurrency like erlang

well-designed like C, Python

encourages readable code like Python

good programming language for prototyping/writing programming languages in, like Racket

like squeak, but based on plaintext source code files, and tooling that interoperates more with the outside world (e.g. conventional text-based source code editing, IDEs) (see also http://stackoverflow.com/questions/5833619/how-can-i-dump-all-the-source-code-from-a-squeak-smalltalk-image )

reference implementations and prototyping of networking protocols and components (since performance is not a goal it may not be the best language to write productions versions in, though)

performance is not a goal (although we would like to architect the language so that in theory it could be made performant later; however, without actually trying to make it performant we'll probably miss lots of stuff)

like perl, good for writing one-liners from the commandline (including syntactic sugar for regexes), but readable like python

a 'glue language': have an existing application written in Python, and want to keep developing it using Jasper? That's easy. Have an application in Haskell, want to keep developing it using Jasper, while making use of some libraries in Python and Java? That's easy.

---

Prime-priority list of features/design goals

todo not in prioritized order, not in correct major/minor/supp lists

Major features / high-level design goals

Minor features / mid-level design goals

Supplementary features / low-level design goals

Prime-priority list of application domain design goals

Why NOT Jasper? Prime-priority list of disadvantages/design anti-goals

Major disadvantages / high-level design antigoals

Minor disadvantages / high-level design antigoals

Details on things in the prime-priority lists

---

some old versions :

Simple, expressive

Simplicity means minimization of the number and difficulty of concepts and details. (todo do better here; it's really something having to do with the difficulty of thinking in the language, and of remembering the language)

simple, small

todo

layered: core, language, standard libraries

expressive

todo

relation to powerful: if by 'powerful', it is meant, 'enough features so that i can do what i want without writing much new code', then we are focused not so much on providing every desirable feature within the language, but rather upon making the language expressive enough so that it's possible to write a library for that feature that allows source code using it to read naturally.

todo mechanistic concepts are simpler than others

'expressing computation in a natural way rather than bending it into a non-intuitive form to fit it into the language's paradigm'

Readability

by readability we mean that the time necessary for an advanced Jasper programmer to understand someone else's source code is minimal.

todo

Jasper strives to have 'scannable' syntax; meaning that your eye can quickly scan through code looking for where a certain thing occurs.

todo

Also, a word about simplicity, size, and learnability. Jasper is a simple, small language which is easy to remember. However, although the language is small, it has a large standard library, so in order to become fluent in Jasper idioms and read others' code there is a bit to learn. Jasper is focused on being easy to remember, but not necessarily easy to learn; what I mean is that it may take you more than a few days to grok it, but once groked, you should be able to work on it on weekends every now and then without having to spend a lot of time getting back up to speed.

todo

relation to concise: we value conciseness but we see this as only a means to the ends of expressivity and readability. Insofar as 'concise' just means 'i want to write it the way i think of it', that's what we're calling expressiveness. Insofar as lack of boilerplate makes it easier to see what code is doing, we value reduction of boilerplate. Insofar as making programs shorter makes them easier to quickly understand, we value making them shorter. But insofar as 'concise' means 'Making programs really short by inventing non-intuitive abstract operators that must be 'unpacked' by the reader to understand the program', we disagree. We would rather have you write more code if that will help someone else understand it quicker.

(note: non-intuitive abstract operators are fine with us if their usefulness is broad enough to make it worthwhile for every advanced user of the language to learn them; but not if they are application domain specific. But we still don't want to add too many non-intuitive abstract operators to the language, because that impairs our other goal of simplicity.).

Massive concurrency

Our brain's neurons are individually slower than computer CPUs, but it makes up for this by having a lot of them. Moore's Law isn't increasing CPU clock speeds at an exponential rate anymore, but instead it is giving us the possibility of many processors working in parallel. Together, these show that it is possible to do interesting things with massive concurrency, if only we knew how to write software that could use it. Jasper is a platform for experimenting with ways of writing massively concurrent software.

todo

high-level: opinionated, for less-leakly abstractions in which the tradeoff is performance (rather than flexibility)