shithub: docs.9front.org

ref: bedac6438461449392694dd8c4a7028ccdc46019
dir: docs.9front.org/language-ideas.md

View raw version
# Language Ideas

This is meant to be more of a brainstorming thing than a specification.

## General Spirit

* minimum-noise
* trying to find a middle ground between imperative and FP that isn't just mashing the two together blindly
* readable (but not in some silly "looks like English" kind of way)
* writable WITHOUT an IDE / fancy editor.
* simple, as long as it doesn't compromise anything else. NOT C++.
* don't want to worry about abuse potential, trust developer to be sensible
* ultimately translates to C / machine code. but earlier implementation might be byte code

## Syntax

* good syntax is important, but don't fall for syntactic sugar or trying to make things too cute (fucking scala...)
* braces and semicolons
* generally a "flat" style is easier to maintain and debug imho, even if it's technically longer (where do you even add debug-prints in a giant stack of higher level functionals? unix pipelines are slightly easier here but not much)
* C-style type notation are too hard to parse and too hard to generalise for things like tuples, it's probably not worth it.
* postfix notation is surprisingly useful (think unix pipes)

## Type System

* some weird merger of Go and ML?
* want structs, union types, tuples
* haskell typeclasses / go interface
* parametric polymorphism

## OOP

* Basically, no.
* However, methods solve some tricky namespace problems. Maybe worth it?

## Modules

* Basically, Go.

## "Data-driven thinking" / Traits

In C you often end up with giant structs which looks like

	struct MegaStruct {
	a bunch of properties used by all
	...
	a bunch of properties only used by code A
	...
	a bunch of properties only used by code B
	...
	a bunch of properties only used by code C

This is bad for modularity, but there isn't a nice way (in C) to avoid it.
What you really want is a way to specify these things separately, together with the code that manipulates them; in fact keeping them separately in memory might be a good idea too (improves cache locality).
One approach is to define a bunch of "traits" like

	trait MegaStructPartA {
		only those properties used by A
	}

An object is then only an accumulation of certain traits.

## Testing

* Being able to specify test-cases in-line seems like a good idea.
* Also properties for quickcheck-like testing

## Crazy Ideas

* laziness-on-demand: values can be lazy, so that you can do things like
		a = async request_a();
		b = async request_b();
		c = a + b;
	which issues both calls simultaneously.
* labels-as-closures: a goto-style label can be used in an expression to create a closure for the rest of the function