0% found this document useful (0 votes)
81 views43 pages

Transcribe 2

This document discusses various potential language features including: 1. Loop syntax alternatives like 'forall' and 'where' clauses for array updates. 2. Regular expression features such as long-form regexes and named/documented regexes. 3. FLWOR clauses for XML processing and potential additional clauses like 'window', 'count', and 'group-by'. 4. Operators for sequences like union, intersection, subtraction. 5. Matrix multiplication and differentiating between vectors and matrices. 6. Potential functions like 'hook', 'fork', 'pamf', and convolution.

Uploaded by

csis122labs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
81 views43 pages

Transcribe 2

This document discusses various potential language features including: 1. Loop syntax alternatives like 'forall' and 'where' clauses for array updates. 2. Regular expression features such as long-form regexes and named/documented regexes. 3. FLWOR clauses for XML processing and potential additional clauses like 'window', 'count', and 'group-by'. 4. Operators for sequences like union, intersection, subtraction. 5. Matrix multiplication and differentiating between vectors and matrices. 6. Potential functions like 'hook', 'fork', 'pamf', and convolution.

Uploaded by

csis122labs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 43

'cycle' instead of 'break'?

implicit 'do' loops in some way?


* would yield an array/list
* what would the introduction syntax look like?

'forall' loop
forall x = 1:5 where x + 1 == x -1
* executes for everything initally specified that satisfies the where

'where' clause assignments - allow bulk updating of elements of an array


int[] a = new int[1, 2, 3]

where (a >= 2) {
a = 0
}
z
// Can use 'else where' for chaining
where (a > 0 && a < 2) {
a = 0
} else where (a >= 4)
a = 1
}

long-form written regexes (see rx.txt and rx2.txt)


General syntax like:
or A B
# also
or
A
B
Parens may be added as desired: no pairs for python style, one pair for C
style, two pairs for lisp style

These regexes can be named/documented/referenced via other regexes (regexen?


regexi? regices? all vaguely plausible, but kind of silly looking, and
etymologically suspect).

FLWOR: for, let, where, order by, return


for: create seq. of nodes
let: bind variables from the seq.
where: filter out nodes from the seq.
order by: sort node
return: eval'd once per node

sequence union/intersection/subtraction (except)


[1, 2, 3] union [2, 3, 4] = [1, 2, 3, 4]
[1, 2, 3] intersect [2, 3, 4] = [2, 3]
[1, 2, 3] except [2, 3, 4] = [1]

Possible additional FLWOR clauses


window: go over a windowed seq. of nodes
Two window types
* tumbling: non-overlapping
* sliding: overlapping
count: bind a variable to the seq. index
group-by: aggregate nodes into groups off of conditions

long-form regex types


int: integer numbers
range: range of integers
str: string
char: characters
rx: regex
cclass: character class
bool: boolean

perhaps WS sensitive (during reading, tabs convert to configurable # of


spaces)

generalized matrix product


combine MxN and NxR matrix (2D array) into MxR like
C(I, J) = A(I, 1) * b(1, J) + ... + A(I, N) * B(N, J)
where I and J are indices

differentiate between 1xN matrices and vectors?

hook f g x = x 'f' (g x)
fork f g h x = (f x) 'g' (h x)

'pamf' - apply a list of functions to a value to get a list of values


pamf :: [a -> b] -> a -> [b]

convolution
c(k) = sum(i+j = k): a(i) * b(j)

(sqrt(.) * x + (1/.) * 1) (.) (9x + 4) =


sqrt(9) * x^2 + sqrt(4) * x + (1/9x) + 1/4 =
3x^2 + (19/9)x + 1/4

associative, not commutative, [id] is the identity

'salign' - vaguely like zipping two lists, but when one list runs out, just insert
the items from the other list
'malign' is similar, but uses a default value standin for the missing element

(perhaps better think of 'salign' as 'semi-align')

'these' - values w/ two non-exclusive probs.


These A B = (A + B + AB)
Either A (B, Maybe A) is another (somewhat confusing) way

consider the function


align :: f a -> f b -> f (These a b) (where f is an arbitrary generic type)

construct it with 'this' (left), 'that' (right) or 'these' (both)

here :: (a -> b) -> These a c -> These b c


over :: These a b -> These b a

[[f x y]] = (pure f) <*> x <*> y

multiple return points


- follow a function call w/ n expressions, eval'd based on labelled return
points in the function

adverbs
':' followed by a name, changes the behaviour of the previous
operator/expression bit

'main' CLI arg generation


allow arbitrary arg. signatures from main, and auto-generate a CLI interface
from that

regex comments - (?#<comment>)

'trx' - tree regular expressions

variable vs container
This is a thing borrowed from perl 6 as it were, and is sort of equivalent to
the idea of every variable being in a 'implicit monad' or something like that
(though without the behavior guarantees). Essentially, the idea is that each
variable has both a type that it contains (like String or Int) and a type that it
is (like Scalar or Array). This helps with keeping structural concerns separate
from functional ones.

The syntax for it could be something like


Scalar : Int asdf = 1;
though I'm not sold on it

regexp features
\%[...] from vim - match atoms until one fails to match
\%<num>c - matches at a specific 'virtual' column (tabs count as 1+ columns)
\%<num>C - matches at a specific 'absolute' column
For the above, add a '<' or '>' to match before/after it

relative v. absolute tabstops


Absolute tabstops move a fixed # of spaces per tab, while relative tabstops
move to the next tabstop, however many spaces that is

vertical tab - six lines

ASCII 28-31 separators


file/group/record/unit/'word' (space)

ASCII 14-15
Shift In/Out

(*POST:<name>) - mark this position as <name>

'entangled' variables
Declared as a function/variable pair. Calling the function updates the
variable from anywhere.

'procrastination' java library


implements recursive trampolines/fixpoints

'splat' :: (a -> b) -> a[] -> b[]

semi-pattern matching via overloading?

checkpointable
checkpoint() : void -> boolean
rollback() : void -> boolean
commit() : void -> boolean
commitAll() : void -> boolean
rollbackAll() : void -> boolean
inCheckpoint() : void -> boolean

machine vs user-level equality


Many languages have a notion of machine-level (bit pattern) equality for
types; and they also have a notion of 'user-level' equality for types. For many
types these are the same, but the main one where the notion becomes somewhat
problematic is with floating-point numbers. This is because of things like the fact
that NaN is a thing (and there are multiple ones), as well as there being a
distinction between -0.0 and 0.0 (which the machine may care about, but users
generally don't)

One idea on how to deal with this, is to have two different types of
equality/comparison types, one for each. This could be Equals(User
equality)/Identity(Machine equality) and Comparable(compare by
user-level)/Sortable(compare by machine-level)

Stack stuff
-- PRIMITIVES
first :: (x~>x')*(x*y) ~> (x'*y)
swap :: (x*y) ~> (y*x)
assocl :: (x*(y*z)) ~> ((x*y)*z)
intro1 :: x ~> (Unit*x)
elim1 :: (Unit*x) ~> x

-- SOME DERIVED PLUMBING


assocr :: ((x*y)*z) ~> (x*(y*z))
assocr = swap assocl swap assocl swap

rot2 :: (x*(y*z)) ~> (y*(x*z))


rot2 = assocl [swap] first assocr

second :: (y~>y')*(x*y) ~> (x*y')


second = swap [swap] first swap first swap

rot3 :: (a*(b*(c*d))) ~> (c*(a*(b*d)))


rot3 = [rot2] second rot2

zip2 :: ((a*b)*(c*d)) ~> ((a*c)*(b*d))


zip2 = assocr rot3 rot2 assocl

allow giving names to lambdas (like in JS) - this can improve lambda-heavy stack-
traces

One good idea is to give functions colors in some way, so as to allow them to be
'polychromatic'
In the article this idea came from, color was a metaphor for async functions,
due to their special behavior. Are there any other interesting ways to split
functions by color in a non-arbitrary way?

mixin functions - subclasses without parents.


Per my notes, you are grafting parents onto a copy of a subclass.
Unfortunately, my notes don't give any indication as to the idea source, or what
the motivation was. I am going to assume it was something along the line of perl
6's trait/role system.

pope operator - <+|:-)


Or other ending variants (<+| is the hat)

reservoir sampling
to select K elements randomly from a stream of unknown size, where N is the
number of elements seen so far, select each element with probability K/N, replacing
a randomly picked element if our selection is full.

non-prime number regex (in perl)


/
^1?$
|^(11+?))\1+$
/x

regex for solving ax + by = c


^(.*)\1{A-1}(.*)\2{B-1}$

Run against a 'c' length string, and the length of each capture group is the
value of that variable. Can be expanded fairly easily to accept more terms.

Dynamic regular expressions using {{...}} and maps

|> - Pipeline operator


a |> b |> is c(b(a))
Use <| to do it in inverse

?? - Null coalescing operator: Returns the non-null arg, short-circuiting

? Placeholder
When using a function in a context where only one arg is expected to go,
indicates where it should go

More particularly, it converts a normal function call into a partially


applied function call. Follow with a colon then a number to allow re-use

Tag literal strings as literals, as well as results from literal operations

In block literals passed as arguments to something, use :: to access args from the
parent.

stride from ... to... by... - Int range operator

guard <expr> <block>


If expr is false, executes block, which must leave the enclosing block

select... when... otherwise... - alternative case syntax

'using <expr> <block>' - automatically disposes of 'expr' after executing 'block'

Functization - Allow conversion of args. to lambdas

In block-args cases, use @return to return from the enclosing scope


Maybe have two different block-arg syntaxes? One which catches returns, and
one which doesn't

Regex construct for attempting to match sub-patterns, in any order

Substitution back-reference conditionals


${group:+matched:unmatched}
inserts 'matched' when the group participates, and inserts 'unmatched'
otherwise.

relative backreferences?
subroutine recursion
Attempt to match a particular subgroup

\K - keep: Consider match to start at this point

(?| - Branch Reset Group: Each alternative starts at the same subgroup number

(?> - Atomic Match: Upon success, throw away any backtracking points created inside
the group

Regex construct for checking if a capturing group matches a given regex

(?< - Named capturing group: Pushes capture value onto main stack

(?<- - Capture subtraction: Pops one item from the main stack. If none exist, fails
and causes backtracking.

double-quoted string regex: "(?:[^"\\]+?|\\.)*+"

some regex construct for using 'sub-captures' from recursive/sub-calls

(?~ - Match Negation: Matches any non-matched regex

In a balanced group, follow a group name to only succeed if the captured value
matches a given regex

:;: - Lambda-glue operator: Glues lambdas together into a 'overload-lambda'.


Calling the result will call the matching functions
Perhaps some way to specify how many matching functions are called, if there
is more than one? Probably something using a perl-style adverb

Magical variables - Create a 'wizard' who will 'cast' upon a variable, imbuing it
with 'magic'. Use the 'dispel' keyword to remove the magic. Multiple wizards can
cast on a variable, and can be dispelled independently of each other (dispel by
wizard name?). Wizards can cast multiple 'spells', and which one is cast on a given
variable can be determined by the name/type of variable

Devel::Declare may be interesting

Enchanters
Work for functions like wizards work for variables. The main difference is
that 'magic' from wizards is attached to a specific variable. Enchantments are
attached to a function, and if that function happens to be bound to multiple names,
they will share the enchantment. However, each name can have its own 'magic'
associated with it.

Keywords are 'enchanter', 'enchant' and 'disenchant'. An alternate set is for


'blessing' with keywords 'ordain', 'bless', 'curse'

Given can be used to group tests for operations with respect to common initial
state
When can be used to group tests by operation, regardless of initial state or
outcome
Then can be used to group tests by common outcome, regardless of operation or
initial state

Optional<Integer> first = getFirst();


Optional<Integer> second = getSecond();
// Add first & second, treating 'absent' as zero, and returning an optional.
// If both are absent, return an absent optional
Optional<Integer> result = first
.map(arg -> second.map(arg::add).orElse(arg))
.map(Optional::of)
.orElse(second);
// Prove this is always correct

// Y-combinator in Java, or at least one variant of it


interface Y<ArgType, RetType> extends Function<ArgType, RetType>{
public RetType process(ArgType arg, Y<ArgType, RetType> func);

default RetType apply(ArgType arg) {


process(arg, this);
}
}

class Holder<ContainedType> {
private ContainedType value;

public <RetType> withContext(Function<ContainedType, RetType> action) {


return action.apply(value);
}

public <ArgType, RetType> Function<ArgType, RetType> liftWithContext(


BiFunction<ContainedType, ArgType, RetType> function) {
return (arg) -> function.apply(value, arg);
}
}

// Anagram reader - streams gone mad!


try (Stream<String> words = Files.lines(dictionary)) {
words.collect(
groupingBy(word ->
word.chars().sorted().collect(
StringBuilder::new,
(sb, c) -> sb.append((char)c),
StringBuilder::append
).toString())
).values().stream()
.filter(group -> group.size() >= minGroupSize)
.map(group -> group.size() + ": " + group)
.forEach(System.out::println);
}

Smalltalk style browser for Java?

Add structured-regex style interface for delimgroups

>>/<< as function composition operators e.g: f >> f >> h = h(g(f(x))) or f << g <<
h = f(g(h(x)))

named lambda syntax: fn <name> <args> => <body>

overstrike controls - given two characters, second can be overstruck left, right or
center. Center is traditioal overstrike, while the others are offset by 1/2 char
width
Result type, consisting of 3 things
Possible return value
Zero or more warnings
Zero or more warnings

'bind' for inflection strings to replace var. refs with values


'long form' parsing/unparsing support for inflection strings
'short form' unparsing for inflection string

rewritefs

stfl library/spl language

lmbench - bargraph (1)

desk & funky - shell utilities

/* Resource abstraction from Spring. Intended to augment URL, which is missing a


few features. */
public interface Resource extends InputStreamSource {
boolean exists();
/* If this returns true, this is the actual resource, not a descriptor of it.
This means that the resource is single use, in that every call to getInputStream
will return the same stream. */
boolean isOpen();
URL getURL() throws IOException;
File getFile() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
public interface InputStreamSource {
/* Yields an input stream. Should return a fresh input stream, which the
caller should close at some point. */
InputStream getInputStream() throws IOException;
}
public interface ResourceLoader {
Resource getResource(String location);
}

target-typed constructors - when the type you are attempting to construct is


unambiguous, you needn't specify the type with the new, e.x: Point[] points =
{new(1, 2), new (3, -2)}. If a constructor isn't matched on the specified class,
check any subclasses/classes which are convertible to the target.

partial switch statement - shortform for calling a predicate with different args;
e.x:
pred = (arg1, arg2) -> ...; # pred has type arg1:A -> arg2:B -> bool
switch-by (pred) {case 1, 2: ...; case 3, 4: ...; nest _, 3: {case
2: ...; ...} ...};

in the case-expressions, you can specify the args either positionally or by


name; the nest expression allows you to more easily test multiple cases with a
shared argument.

There is a possible generalization as follows


func = (arg1, arg2) -> ...; # func has type arg1:A -> arg2:B -> C
switch-on(func) {case 1, 2 => 3: ...; nest 3, 4: {case 2: ...; ...} ...};
The main thing here is the 'arrow' notation for cases, though that is not
final from a syntactic perspective. If you do not specify this, then it will
execute that case by default. The expression to the right of the arrow can be an
arbitrary pattern-matching expression, not just a single value. This is helpful
when you have a complex return type, or multiple return types.

There is also special support for things which return functions. You can use
'->' instead of '=>' to say that you want to call the item, and then specify the
set of parameters for it that way.

You can also use ~> to perform manipulations of data, by following it with an
expression.

dice things
alias die -> int RNG
alias dice [] die
alias multidie -> [] int RNG
alias multidice -> [] multidice

gen-type dxp dtype


field exp dtype
field primary dtype
field tag string
field type symbol

alias diexp bind dxp die


alias dicexp `dxp dice
alias multidiexp `dxp multidie
alias multidicexp `dxp multidice

proto constant diexp int


proto roll dicexp diexp diexp

proto-set primary
diexp diexp
dicexp dicexp
proto-set secondary
diexp diexp
dicexp dicexp

proto multi dicexp diexp


proto select diexp diexp diexp

proto pool dicexp [] | diexp dicexp

proto filter dicexp (-> bool int) dicexp

proto map dicexp (-> diexp diexp) dicexp


proto zip dicexp (-> diexp diexp diex) dicexp dicexp

`foreach typ diexp dicexp


proto add $typ diexp $typ
proto sub $typ diexp $typ
proto mul $typ diexp $typ
proto div $typ diexp $typ

proto-set tag
diexp string diexp
dicexp string dicexp
proto-set repl
dicexp diexp diexp
dicexp diexp dicexp

proto reduce diexp (-> diexp diexp diexp) diexp dicexp

proto flatMap dicexp (-> dicexp diexp) dicexp

proto rollN dicexp dicexp int

proto-set predicizize
(-> bool int) dicexp diexp
(-> bool int) dicexp dicexp

C# annotation based test cases


[RowTest]
[Row(@"NotAnEmail", false)]
[Row(@"@NotAnEmail", false)]
[Row(@"""test\\blah""@example.com", true)]
[Row(@"""test\blah""@example.com", false)]
[Row("\"test\\\rblah\"@example.com", true)]
[Row("\"test\rblah\"@example.com", false)]
[Row(@"""test\""blah""@example.com", true)]
[Row(@"""test""blah""@example.com", false)]
[Row(@"customer/[email protected]", true)]
[Row(@"[email protected]", true)]
[Row(@"!def!xyz%[email protected]", true)]
[Row(@"[email protected]", true)]
[Row(@"[email protected]", true)]
[Row(@"[email protected]", false)]
[Row(@"[email protected]", false)]
[Row(@"[email protected]", false)]
[Row(@"[email protected]", false)]
[Row(@"""Austin@Powers""@example.com", true)]
[Row(@"[email protected]", true)]
[Row(@"""Ima.Fool""@example.com", true)]
[Row(@"""Ima Fool""@example.com", true)]
[Row(@"Ima [email protected]", false)]
public void EmailTests(string email, bool expected)
{
string pattern =
@"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);

Assert.AreEqual(
expected,
regex.IsMatch(email)
, "Problem with '" + email + "'. Expected " + expected + " but
was not that.");
}

Filename falsehoods
Falsehood: The path component separator is always / or . Counterpoint: On
MacOS 9 the path component separator was :
Falsehood: Windows UNC paths \FOO refer to a network server.
Counterpoint: \.\COM1.
Falsehood: Absolute Windows paths always begin with DRIVELETTER:.
Counterpoint: \?\C:\Foo. This is the long path support, the \?\ prefix is used to
indicate the application can support long paths.
Falsehood: Windows UNC paths begin with \SERVERNAME. Counterpoint: \?\UNC\
SERVERNAME. \?\UNC\ is the long path UNC prefix.
Falsehood: A subdirectory of a directory is on the same physical storage on
Windows. Counterpoint: Drives can be mounted at arbitrary directories, not just at
drive letters.
Falsehood: Barring symlinks and hardlinks, a file has only one path which can
access it. Counterpoint: File paths can contain redundancies like /./, leading to
an arbitrary number of strings accessing the same file.
Falsehood: Barring symlinks and hardlinks and with paths normalised to remove
redundancies, a file has only one path which can access it. Counterpoint: The same
filesystem can appear at different mountpoints on *nix using bind mounts. On
Windows, junctions can be used, which function similarly to directory symlinks, but
which are not symlinks and which are substantially more transparent.
Falsehood: If a Windows path has a drive letter, it must be an absolute path.
Counterpoint: C:foo.txt (or C:bar\foo.txt or C:..\bar\foo.txt) is relative to the
current working directory which was last set for C:, which may be different to the
current working directory for the current drive letter.
Falsehood: Barring symlinks or hardlinks, a file has only one name.
Counterpoint: Short names on Windows. C:\LongFilename.txt is reduced to C:\
LongFi~1.txt for legacy access.
Falsehood: A short name will always end in ~1.EXT. Counterpoint: If C:\
LongFilenameX.txt and C:\LongFilenameY.txt both exist, one will be C:\LongFi~1.txt
and one will be C:\LongFi~2.txt. Which is which is indeterminate.
Falsehood: Opening a path successfully means you've opened a file.
Counterpoint: Directories (and sockets, and so on) can be opened on *nix. On
Windows, alternate file streams are addressed with the colon, which are
subcomponents of files.
Falsehood: A file only has one stream of data associated with it.
Counterpoint: Windows has alternate file streams. MacOS has resource forks.
Falsehood: A filesystem supports filenames longer than 8+3 characters.
Counterpoint: DOS is limited to 8 characters before the file extension and 3 after.
Falsehood: If you write to a file with provided normalised path X and then
delete normalised path Y, where Y != X, X will still exist. Counterpoint: On
Windows, if X is an alternate file stream path (C:\Foo.txt:sub1), and Y is the file
path (C:\Foo.txt), deleting Y will delete X. Also if Y != X is a case sensitive
comparison and the filesystem is case insensitive.
Falsehood: The types of objects which can appear on a filesystem is limited
to files and directories. Counterpoint: Windows has files (including hardlinks),
directories, symlinks, junctions. *nix has files (including hardlinks),
directories, symlinks, sockets, FIFOs, character devices, block devices. Some
*nixes may have other object types, like Solaris doors.
Falsehood: A platform provides or doesn't provide mandatory locking.
Counterpoint: Windows does and it is used by default. Linux doesn't provide
mandatory file locking.
Falsehood: A filesystem mounted on *nix is always case sensitive.
Counterpoint: Linux can mount FAT32, NTFS, etc.
Falsehood: A filesystem mounted on Windows is always case insensitive.
Counterpoint: Windows can be configured to make its filesystems case sensitive.
Falsehood: The separators between multiple directory components are the same
as that used to separate the directory components and the filename. Counterpoint:
OpenVMS paths look like this: SYS$SYSDEVICE:[DIR1.DIR2.DIR3]FILENAME.EXT;FILEVER.

Do something like PHP 'constructor property promotion'


class Point {
public function __construct(public float $x = 0.0, public float $y =
0.0, public float $z = 0.0) {}
}
This declares properties X, Y and Z on the class, with the given default
values. You can still put a body in the constructor, and that will run after the
initialization of the given values. In PHP, using both this syntax and the normal
property syntax causes an error about attempting to redeclare a value. However, I
could see a fairly intuitive way to do it where it would only give an error if the
declarations were incompatible.

An interesting possibility is to allow this for non-constructor methods as


well, though that could cause some confusion as to what exactly the fields of a
class are, and what their default values are.

An alternate possibility would be something like the notion of


'primary/secondary constructor' from Kotlin. This looks like
class Employee(private int salary, public String firstName, public
String lastName) {}
// called like new Person(600, "John", "Doe")
// Can declare default args and all other sorts of parameter
expressions.
You can have secondary constructors, but every secondary constructor must
call the primary constructor, either directly, or indirectly.

To allow for easier inheritance, you can use the following syntax
class Supervisor(int salary, String firstName, String lastName, public
Employee... supervised) extends Employee(salary * 1.5, firstName, lastName) {}
// Could call any constructor of employee, not just the primary one.
Note that the inherited parameters are missing visibility specifiers. If you
did add a visibility specifier, in general, you will get a 'property override',
unless the specifier is less visible than one in the superclass. In that case, you
get an error (There are ways to to make it not an error, but that may cause more
confusion than necessary).

Anonymous classes can also use this syntax, though it is less than
syntactically pretty.
class Person(public String firstName, public String lastName) {...}
Person pers = new class("John", "Doe", "M")(String firstName, String
lastName, public String middleName) extends Person(firstName, lastName) {...}
// The arguments come before the constructor specification, because of
how anonymous class syntax works.
This works with multiple inheritance in exactly the way you would expect.

Projected values - One thing that often happens with objects, is that you have a
property which is determined solely from other properties of the object, but that
is expensive to compute for whatever reason. So you would want some easy way to not
compute it more than necessary, but to make sure that it never gets out of date.
One syntax could be
struct nums {int a; int b; projected int sum(a, b) {sum = a + b}};
where accessing sum will calculate it, but changing either a or b will mark sum as
'dirty' and cause it to be recomputed upon next access. One note is that you could
say that sum only depended on a, so changes to b wouldn't cause sum to be
recomputed. You could also explicitly mark it by saying 'dirty sum'. This will work
recursively, though it might cause some interesting performance behaviors if you
aren't properly careful. Note that an explicit assignment to these values won't
work, though I could imagine an ability which would allow you to do so.

PHP enum syntax?


interface Colorful { public function color(): string; }
enum Suit implements Colorful {
case Hearts = 'H' { public function color(): string { return "Red"; }
public function shape(): string { return "Rectangle"; }
}
// Should this work? public function stuff(Suit::Heart|Suit:Diamond $card)
{ ... }
enum Distance { case Kilometers(public int $km); case Miles(public int
$miles); }
// Use the parens to declare 'tagged' objects
// Another example
enum CardinalDirection { case North, South, East, West; }
enum Direction { case Left, Right; }
enum Command {
case Move(public CardinalDirection $direction, int $distance);
case Turn(public Direction $dir);
case Shoot;
}

Interesting idea: Track which constructor (and with what arguments) something was
created, and allow a 'reset' operator which will replace the object with one just
as if it was newly created

'fun' gotcha - When using a null-safe call (like ?-> from PHP), whether or not
function arguments are evaluated can be 'interesting' if you say that arguments are
evaluated.

JS spreadsheet
for (var i=0; i<6; i++) {
var row = document.querySelector("table").insertRow(-1);
for (var j=0; j<6; j++) {
var letter = String.fromCharCode("A".charCodeAt(0)+j-1);
row.insertCell(-1).innerHTML = i&&j ? "<input id='"+ letter+i
+"'/>" : i||letter;
}
}
var DATA={}, INPUTS=[].slice.call(document.querySelectorAll("input"));
INPUTS.forEach(function(elm) {
elm.onfocus = function(e) {
e.target.value = localStorage[e.target.id] || "";
};
elm.onblur = function(e) {
localStorage[e.target.id] = e.target.value;
computeAll();
};
var getter = function() {
var value = localStorage[elm.id] || "";
if (value.charAt(0) == "=") {
with (DATA) return eval(value.substring(1));
} else {
return isNaN(parseFloat(value)) ? value :
parseFloat(value);
}
};
Object.defineProperty(DATA, elm.id, {get:getter});
Object.defineProperty(DATA, elm.id.toLowerCase(), {get:getter});
});
(window.computeAll = function() {
INPUTS.forEach(function(elm) {
try { elm.value = DATA[elm.id]; }
catch(e) {}
});
})();
When a cell loses focus, its value expression (formula or number) is stored
in localStorage, and every cell value is recomputed in the computeAll function. The
computeAll function simply assigns each cell a value that's supposedly stored in
DATA[cellIndex]; only that that value isn't there yet. The expression
Object.defineProperty(DATA, elm.id, {get:getter}) makes sure that everytime I try
to access an index in DATA, the getter function is triggered. So when we say
DATA[cellIndex], it triggers. The getter function returns a value according to the
expression stored in localStorage for the current cell's index. If the expression
is a formula, it runs the expression with (DATA) return eval(value.substring(1)).
This is where the recursion happens, because with(DATA) return
eval(value.substring(1)) is going to iterate through DATA's properties, which as
stated, will trigger the getter function in each access: a recursion is happening;
the termination clause of the recursion is the sentence else { return
isNaN(parseFloat(value)) ? value : parseFloat(value); }. There you have it. A
combination of proxying localStorage and intercepting DATA's properties accesses is
the cause of death... I mean, the key for the formula calculations.

Allow specifying anonymous catches try {...} catch (PermissionException) {...}

Another 'interesting' idea: allow full code execution during compile-time, but
interact with complex rules about when and how many times a given piece of code is
executed to allow side-effecting code to cause 'fun' things to happen.

Statement/expression local bindings - This is a idea heavily inspired by a python


feature
x = [y :|= 2, y + 1, y + 3] # :|= defines a statement-local variable, which
is visible inside this statement
# The above binds x to the list [2, 3, 5]
z = [x :|= 3, 1, x + 1] # Yields the list [3, 1, 4]
# :|= does shadow existing variables on the statement level.
z = z :|= [1, 3], [6, 7, z[1]] # z is bound to the list [6, 7, 3], but goes
out of scope when the statement ends
# Assigning to statement-locals can have less-than-intuitive side effects,
given that they go out of scope when the statement ends
# There is an open question about how to treat reads of a statement-local
before the assigned expression is written to
# The most 'obvious' way to do it, would be to say that statement-locals get
'hoisted' to the earliest possible point in the statement
# The other would be to say that the name becomes 'active' as soon as the
statement starts, but doesn't get a value until the :|= is executed. This could be
'fun' when mixed with shadowing, because usage before initialization would get the
shadowed value.
# There is also |:= which is an expression-level binding. See PEP 572 for
more details
# Note that while this will work for multi-variable bindings, it will not
work for assigning to anything more complex than a name.
# One could support the full degree of compound assignment operators, but
that starts to look very confusing to anybody reading it. :|<<= anyone?
# One of the major benefits is with compound statements. For instance...
if (x :|= pred()):
... # x is bound here
else:
... # x is also bound here.
# x goes out of scope here.
# Another example or two that shows a slight special-case with the scoping
rules
if any((comment := line).startswith('#') for line in lines):
print("First comment:", comment)
else:
print("There are no comments")

if all((nonblank := line).strip() == '' for line in lines):


print("All lines are blank")
else:
print("First non-blank line:", nonblank)

# Map deconstruction syntax


{"host": host, "port": port, "mode": =="TCP"} = settings

# statement if/elseif/else
(if <cond1>: <expr1> elif <cond2>: <expr2>... else: <exprN>))

# 'Circuit-breaker' overloading
_cb = COND
_type_cb = type(cb)
if _cb:
_expr_result = LHS
if hasattr(_type_cb, "__then__"):
_expr_result = _type_cb.__then__(_cb, _expr_result)
else:
_expr_result = RHS
if hasattr(_type_cb, "__else__"):
_expr_result = _type_cb.__else__(_cb, _expr_result)
# There is an additional one (__not__) to override '!' instead of doing a
boolean coercion
# Implementing these, plus boolean conversions, in a way that doesn't work
like boolean logic should is a bad idea
# An interesting circuit-breaker type, which will yield a provided value in
certain conditions
class CircuitBreaker:
"""Simple circuit breaker type"""
def __init__(self, value, bool_value):
self.value = value
self.bool_value = bool(bool_value)
def __bool__(self):
return self.bool_value
def __not__(self):
return CircuitBreaker(self.value, not self.bool_value)
def __then__(self, result):
if result is self:
return self.value
return result
def __else__(self, result):
if result is self:
return self.value
return result

When overloading [] on a given type, allow any number of regular & keyword args

dice things v2
alias die -> int RNG
alias dice [] die
alias mdie -> [] int RNG
alias mdice [] mdie
alias bdie -> bool RNG
alias bdice [] bdie
gen-type dxp dtype
field exp dtype
field primary dtype
field tag [] symbol
field label string
field type symbol

alias diexp bind dxp die


alias dicexp `dxp dice
alias mdiexp `dxp mdie
alias mdicexp `dxp mdice
alias bdiexp `dxp bdie
alias bdicexp `dxp bdice

proto-set constant
diexp int
bdie bool
proto roll dicexp diexp dicexp

gen-proto-set (dty)
primary `dxp $dty `dxp $dty
secondary `dxp $dty `dxp $dty

tag `dxp $dty string `dxp $dty


label `dxp $dty string `dxp $dty

gen-proto-set (typ)
select $typ [] $typ diexp
multi (typ) [] $typ $typ
pool [] $typ [] | $typ [] $typ

union types - types which have the members of all their constituents (overlaps only
allowed if they are either unifiable, or methods with disjoint overload sets)

everge
- CLI Testing
- Maybe use mixed-case for flag options? No, use special // F flag control
- File imports? //f control. Also, //x flag (eXport) which marks a pair as
'included upon import'
- Copy pair (//C control): Creates a copy of a pair with a new set of options
- Multibody support (//m control) - Specify the bodies in the control,
separated with //
- Each body can have its own controls, indicated in the normal way
- Use //o control to add multiple copies of a single body?
- guard control: //G - only apply if the guard matches
- -e and -E arguments for inline input (-e for data) (-E for input)
- Remove arguments for control options?
- //g - Guard behavior control - Defines how guards work in regards to multi-
body contexts.
- Mode 0: If a guard is not met, skip the pair.
- Mode 1: If a guard is not met, skip the body.
- Mode 2: If a guard is not met, skip the body and the match
- //Y - Enable cyclic mode (cycles through bodies)
- //y - Cyclic mode control: Switches between the cyclic behavior types
- Type 0: Cyclic, repeat bodies if need be
- Type 1: Greedy, repeat last body

AbbrevTrewe - Tree with node resolution working like name resolution in COBOL. Each
node has a label & data, and you can seek any child node by label, as long as the
node is unambiguous. Can include nodes in the hierarchy to disambiguate.

Add view of AbbrevMap as a Map

ThresholdSet - Set/Map combo. Stores values in the set; attempting to store a


duplicate moves the value to the map, which counts the number of occurrences.
Doesn't directly implement Set/Map, but does present Set/Map views

ErrorTree - Used for representing errors in a tree-like fashion. Supports 4 levels:


error, warn, info, trace. Maybe more or less levels? Also provides counts/easy
string formatting?

fsdb - fast, version controllable token indexer. For each token in a file, creates
a file named after that token, and writes the document name as a line. When
necessary, uses directories to perform stemming.

Multimap - a map that stores a list of keys

ThresholdMultimap - Works like a ThresholdSet, but for key-value pairs; only


considers keys for uniqueness.

jclsh - shell that uses a JCL variant to run jobs. Has a basic command shell to
allow setting up jobs, and then a command to execute a JCL deck. Supports
partitioned data sets & generational data groups.

ExprSet - Contains a set of integer/boolean variables, and equations using those


variables. Can attempt to solve an equation for an unknown variable.

ArraySpace - 3D array with a cursor that can move varying distances/directions and
insert/read data. Possibly make n-dimensional?

smu - Stream Mangling Utility. Performs text manipulations and other related things
in incoming streams of text; commands are based off of the ones for TECO/ed/QED and
the like.

Add header/footer support for ReportWriter


Add ability to config the ReportWriter in CLFormat
Int/Boolean/String vars for CLFormat
Allow item offsets for picking CLFormat items

Operand/Operator Elision - Allow abbreviation of expressions by omission of either


the left-hand operand (subject) or the operator. Borrowed from COBOL. Examples:
a = b and not < c or d -> ((a = b) and (a not < c)) or (a not < d)
a not > b or c - > (a not > b) or (a not > c)
not a = b or c -> (not (a = b)) or (a = c)
not (a = b or < c) -> not ((a = b) or a < c)
not (a not = b and c and not d) -> not ((((a not = b) and (a not = c) and
(not (a not = d)))))

not occlusion - immediately preceeding an operator with the word not/operator


'!' binds it to that operator, not to the enclosing expression
operator elision and parens - Parenthesizing the LHS of an abbbreviated
expression distributes the operator over it

Liberal usage of parens is recommended with operator elision to prevent


confusion of either yourself or others (Note that the compound assignment operators
(+=, -=, ...) start an elision context)
Generally, stacking 'not' causes them to cancel, and a warning to be emitted.
However, usasge of not occlusion can prevent this from happening, if one not
applies to an operator, and the other applies to an expression. Here are some more
examples:

a == b -> a == b
a == b && c -> (a == b) && (a == c)
(a == b) && c -> (a == b) && c
a > b and < c -> (a > b) and (a < c)
a > b and < c or d -> (a > b) && (a < c) || (a < d)
a > b and < (c or d) -> (a > b) && ((a < c) || (a < d))
a not > b or c -> (a not > b) or (a not > c)
a eq b or not not eq (c and b) -> (a eq b) or (not ((a not eq c) and (a not
eq b)))

These rules/examples are somewhat subtle, and might be missing a few cases.
Go figure.

Non-relational operators can be used with coalescing, but the types need to
match up. However, 'or' in that context introduces a junction (two-value/pair) type

Some operations implicitly collapse junctions when all of the values are
equal. Some don't. It shouldn't matter in most cases.

Integrate everge into RGens in some way.

Allow operators point-wise across types (corresponding). Let the types define what
point-wise means for them

Allow assignments with multiple RHS vars (each gets the LHS var).
Find some way to allow them to be different (expr. fragments) ex:
a, ?x + 2 : b, c = z + y; -> tmp = z + y; a = tmp; b = tmp + 2; c =
tmp;

In some cases, a comma counts as an implicit 'and' for operand elision purposes.
ex:
a += b, c -> a = a + b + c

Warning on things opened on one thread and closed on another?

execution labels: applied to arbitrary lines, identifies them for handling


- names use lexical scope w/ hoisting (labels visible before declaration site
in their scope)

goto - jump to another exec. label. May cause bad things to happen if you
jump to a scope that isn't currently active at the moment.

comefrom - Before executing a specific exec. label, start executing at the


comefrom.
If there are multiple comefroms, either do them in some serial order,
or execute them in parallel (possibly with a join on them returning?)

alter - change execution labels at runtime.

talter - 'thread alter' - Alters an execution label only for a given thread,
which shadows any non-thread-local changes

postfix exception handling after func. class - 'on <exec-name> <block>


use 'on-guard' to specify a conditional to use, instead of an exception.
use 'en-garde' to specify a pre-condition (This is just kinda silly, can it
be improved?)

multiple rhs & lhs: use parens to specify which vars are shared (none by default)
ex:
a, b = [1, 2] -> a = 1; b = 2;
(a, b), c = [1, 2] -> tmp = 1; a = tmp; b = tmp; c = 2;

some sort of way to specify how to handle having less vars than expected:
error, default, repeat last, cyclic?

giving/returning - postfix modifier to auto-assign to a return val.

integer divide is a multi-value op, yielding quotient & remainder

multi-variable case (COBOL evaluate)


Specify multiple objects to switch on, and multiple expressions per statement
1:1 mapping of objects to expressions; missing expressions are default
'true', extra expressions are default 'false'
Allow naming of vars/expressions in some way?

goback - return to where you originally were after a goto/comefrom

allow multiple occurrences of an exec. label, and use indexing to pick a specific
one (use * to pick all of them)

for evaluate, have break (exit), continue (eval. next matching), redo (resume
matching from start). fallthrough (exec. next statement unconditionally, regardless
of the normal condition.)

'initialize' - reset vars to their default state.

try and do something like 'INSPECT' from COBOL (see if it can be generalized in
some way; ref. p303)
also, 'UNSTRING' (ref. p392)

call-by-copyback: values are copied into a parameter when a function is called,


then copied back out when the function returns. Can lead to fun behavior with
async. functions

usage of module parameters - :var: is replaced on import. These can be values or


source tokens

Include a built-in source pretty printer (for what?)

Review the TokenSplitter stuff; revise if necessary.

Move delimgroups to their own project (Really? That seems slightly excessive, given
the amount of code in there. I can see why you would want to though...)
Add prioritization (for what, and in what cases?)
Add more markup minimization criteria

'combine groups' - Tokens which introduce multiple groups at once.

allow using different splitters for certain groups. e.x: specify an original
splitter on two consecutive newlines, then specify a splitter to do sub-
tokenization on each line.

vars of some kind?


In general, try and reduce necessary number of delimiters

Add something like LINK from SGML

Command-file set for everge (like TokenSplitter, BlockReader, DelimGroup...)

AbbrevMap - Locate a string with unambiguous abbreviations of it


RStack - A stack with support for having elements that are themselves stacks.
(NestStack?)

Allow introduction of additional vars into lambda closure scopes on lambda decl.

Allow default arguments to reference vars that will be grabbed upon usage - for an
enhanced experience, borrow from Python and allow making default args 'static',
where they will get their value on the first call of the function, and keep it
otherwise

Name shadowing for regex capture groups?

regex capture sets - essentially works like ID from HTML; can have cardinalities

ReductionMap: Key/value map; if a given key isn't found, apply a reduction to the
map and then look again. Allow bounding the attempts of reduction by either
number/predicate or both
ElisionRail - Implementation of shunting-yard that supports operand elision

add return types to signatures for overloading? could require some 'interesting'
changes to however overload resolution/type deduction gets done to ensure that the
'right' version is picked, for some definition of 'right'

overloading of literal syntax


# Map/array literals
class DemoList<T> { def [new](values List<T>) {} }

class DemoMap<K, V> { def {new}(keys List<K>, values List<V>) {} }

@export
def test {
var list DemoList<int> = [1, 2, 3]
var map DemoMap<int, int> = {1: 2, 3: 4}
}

# Piecewise map/array literals


class DemoList {
def [...](value int) DemoList { return self }
def [...](value string) DemoList { return self }
}

class DemoMap {
def {...}(key int, value int) DemoMap { return self }
def {...}(key string, value string) DemoMap { return self }
}

@export
def test {
var list DemoList = [1, "2"]
var map DemoMap = {1: 2, "3": "4"}
}
# Custom XML literals O.o
@entry
def test {
var multiply =
<Reduce start=1 reduce=((a, b) => a * b.value)>
for i in [2, 3, 4] {
<Number value=i/>
}
</Reduce>
document.write(multiply.value)
}

class Node {
var children List<Node> = []

# The compiler uses this function to append children


def <>...</>(child Node) { children.append(child) }

def value double


}

class Reduce : Node {


var start = 0.0
var reduce fn(double, Node) double = null

over value double {


var result = start
for child in children { result = reduce(result, child) }
return result
}
}

class Number : Node {


var _value = 0.0

over value double { return _value }

# Setter functions also work with XML literals


def value=(value double) {
_value = value
}
}

# Allow overriding of assigning to array/map literals


# operator names would be []= and {}=

use 'me' as the pronoun for referring to the current object


in a 'class' oriented (INTERCAL style) language, you could use 'taught' and
'teacher'

create a long-form interface for CLFormat (something like s-regex, probably) to cut
down on the 'demonic line noise' appearance of complex format strings
would want some way to attach comments to the various block bits

stream bookmarking: can insert at any point in a stream, represented as an ordered


sequence, don't appear in the output, can append data to any bookmark, can replace
spans of text between bookmarks, can re-arrange bookmarks, can omit/duplicate
bookmark spans
TriggerQueue - queue that executes an action when it fulfils a condition, such as
size, or a marker item being pushed

Spool - queue that allows multiple producers/consumers to use it without running it


to issues with interleaving different writes. ex.
Task 1 writes a, b, c
Task 2 writes 1, 2, 3
Task 3 reads 1, 2, 3, a, b, c or a, b, c, 1, 2, 3.

spool writers group items into transactions, spool readers only get one
transaction at a time. Writers can release partial transaction items to readers,
but readers won't start another transaction until the one they have has been marked
as completed.

change IO for TechOS to streams/spooling or something like that.

define pronouns/proverbs - these are variables which have lexical lifetime, but
dynamic scope; use 'as' to assign the current binding to one, and it will stay that
until either one is destroyed

allow the introduction of polymorphic vars. from with in a procedural scope

scientific notation for integers?


1e5 = 1*10**5 2e6 = 2*10**6 2e4b2 = 2*2**4
1x2 = 1+10**2 2x5b4 = 2+4**5 1e5e2 = (1e5)e2 =
1*(10**5)*(10**2)
1x2b2e2b4 = (1+2**2)*4**2 = (1x2b2)e2b4 1e2x5 = (1e2)x5 =
(1*10**2)+10**5
1e(2x5) = 1*10**(2+10**5) # This is kinda useless, but can't see why it
shouldn't be possible

could get even more interesting with 'flexadecimal' numbers, where the
various numbers can be specified in other bases besides base-10. Would have to get
'creative' with the letters you can use in literals though. Also, you would perhaps
need to use parens to prevent getting letters used in higher bases for getting
confused with syntactic bits

Could also get fun when starting to use suffix letters to indicate number
types

attempting to assign a non-scalar value to a scalar does an implicit join? not sure
on details, inspired by how perl 5's $a{1,2,3} would do a join on the three
specified keys to get a scalar key
actually, perl uses this for emulating nested hashes, which were otherwise
rather awkward for syntactic reasons. However, it could still be interesting

assignment pronouns (each/the/etc.) - in an assignment, the right-hand side gets


some variables auto-defined (less, if this is a defining assignment)
'the' is the LHS value
'each' is an iterator, given the LHS is iterable
'keys'/'values' for hashes?
implicit prop lookup on LHS (.thing?)

backtracking vars - vars with multiple RHS values


on a backtracking failure, changes the most recently bound one to the next
value, in a hierarchical manner.

providing multiple LHS for a compound assignment (+=, etc.)


a = [1, 2]
*a += 1 # a = [2, 3]

change ?: to ?? !!

use ';' to allow parallel fors, as in Rakudo (perl 6)


for x; y -> a; b (a is from x, b is from y)
for x; y; z -> a (a cycles through x, y and z)

use 'qualify' to put field/method names of an object temporarily into scope

use 'return with' to hand back the lexical scope at that point (not any great ideas
on how to do so when there is an existing return value though)

methods with multiple invokable params. (can use '.' to provide one invocant, all
other must be passed.)
they must be leading parameters, the provided invocant will be elided from
the signature

when using string interpolation (${a} and the like), use ${-> a} to create a
closure or 'lazy string'. These will expand the interpolations every time the
string is used in a context where its value needs to be initialized
by default, closures can either take no parameters, or a single parameter,
which is an outputstream they can write to that has the effect of appending to the
string.

It would be interesting to have some way to specify more parameters for a


closure, but I don't know that it actually buys you anything and it could produce
confusion when you have something that looks like a string, but can't be used as a
string without additional syntax in some way.

when specifying dictionary/map literals, use .xxx for a key name to indicate the
key-name is based off of a variable, and shouldn't be treated as a string.

use 'as' as a general-purpose conversion operator, doing both the traditional


implicit conversions, as well as an explicit conversion that the user has
registered (probably using some sort of trait/type-class like thing) ex:
"yes" as bool -> true "3" as int -> 3

For more complex conversions, you would want the ability to specify
additional parameters to the conversion. However, there is some syntactic question
about where you would put said parameters: on the 'as', or on the target type? The
'as' is probably better for being more clear about what is happening, but might get
syntactically noisy at parts.

Allow using 'as' to convert tuples into instances of classes by calling


matching constructor, if there is one; also, something similar for
maps/dictionaries

use '.@' to force-reference a field, instead of any getter associated with that
field; and use '.&' to get a lambda-reference to a particular method with the
current object bound to it. Using '.&' on a class will create a higher-order
function that takes an instance of the class, and then returns a bound function
that calls the method (perhaps use '.&&' to get the decurried form, which does it
all in one go?)
note that '.&' and '.&&' more accurately capture a overload-set, not a
particular method.

Use '*.' to vectorize an operation across a list/iterable thing. Could maybe


be combined with '.@' or '.&' for some things like '*.@' or '*.&&'. Also, multiple
invocations of '*.' in a single expression dealing with nested lists work fine.

transducers
const transduce = (transformer, reducer, seed, iterable) => {
const transformedReducer = transformer(reducer);
let accumulation = seed;
for (const value of iterable) { accumulation =
transformedReducer(accumulation, value); }
return accumulation;
}

# reducer :: BinaryOperator<A, A>


# transformer :: Function<BinaryOperator<A, A>, BinaryOperator<B, B>>
# seed :: B
# iterable :: Iterator<B>

const map = fn => reducer => (acc, val) => reducer(acc, fn(val));
const filter = fn => reducer => (acc, val) => fn(val) ? reducer(acc, val) :
acc;

auto-convert methods which take an array as the last parameter to a var-args method

pseudo-properties: allow using the '.' field accessor, even without a backing field
if there are getter and/or setter methods

allow passing lambdas/closures to annotation-like things for post-processing

calling 'super' from a trait handler calls the next trait in the resolution list,
if there are multiple implementations of the same trait
also, use the 'withTraits' operator to create a wrapper around a given object
that implements the given traits in addition to whatever interface the previous
object had. Methods from traits will shadow the implementation, but after you run
out of trait implementations to call, 'super' will call the implementation from the
object, then go into its superclass.

use the 'applies-to' keyword on a trait to indicate that a trait can only be
applied to things that are an instance of the given type, or a subtype thereof

'owner' vs. 'this' for closures: 'this' always refers to the closest enclosing
class instance, while 'owner' refers to the closest enclosing object, which could
be either the closest enclosing class, or another closure, if it is defined inside
one.
every closure also has a 'delegate' object which is by default set to
'owner'; however, it can be explicitly changed to a different value by the user. In
the original source (Groovy), any variables which aren't defined in the lexical
scope of the closure are assumed to be defined on the delegate.

add some way to get lvalues from collections

for the feed/backfeed operators, allow a way to specify which arg. is filled with
the fed value

for multi-dimensional arrays, allow using an array as an index to index every


dimension at once.

subject-oriented programming: allow picking which method is dispatched to based off


of the caller, not just the called-on object.
while P undo S odnu -- perhaps do something here?

'redo' in a loop to restart the current iteration, 'retry' to restart the entire
loop.

inspired by Inline::Files in Perl, allow specifying multiple 'data streams' in a


file through the use of __SOME_NAME__ style file handles. Each use of a given name
adds a valid file-handle to a file-global variable. Using the same name multiple
times converts the variable into an array, with each use of the variable appending
a new one to the list.

sub infix:<¯\(°_o)/¯> { ($^a, $^b).pick }

use '...' or something along those lines to specify that you want to implicitly
continue the current line until you have two newlines in a row

provide compound feed operators ==>= and <=== (this last one is syntactically
questionable, but still well-formed. Perhaps do it as =<== instead to make it clear
this is a compound assignment?)
there is also ==< and >== which are inverse feeds, passing args in the
opposite slot, but evaluating the same way. They also have compound forms (==<= and
>===)

can use |=| to join multiple feeds together into a single pipeline

use *|: and :|* to stash/retrieve feed values in a pipeline (ref. CMS
pipelines), use :*| and |*: for feed-in/feed-out to pipelines

The result of |=| expres. is the right-most chain with the fewest feed-outs

Can use |*| for an inline feed in. Inline feed out doesn't seem terribly
useful, but you would spell it :*:

It is a compiler error to build a cyclic pipeline with the various pipeline


operators. Thus, the following things are not allowed
There must be a stage that doesn't contain a feed-in
The same value cannot be the target of a feed-in and a feed-out in the
same stage.
You can feed in/out the same value multiple times in the same stage
You can do the same thing across stages, but the ordering is
deterministic but undefined, so strange behavior may result

use :=: to split things into 'stage groups' which execute sequentially. This
helps the pipeline builder find the right ordering to run things.
use double the ':' on feeds to reach across stage groups. Note that you
can't feed-in values fed-out from a later stage group.

prefixing ^ (or perhaps another symbol) to a variable indicates that it is actually


a parameter in the closest enclosing scope which accepts such things. use multiple
^ as the ability to reach out into further scopes.
these will be appended to the parameter blocks if they exist,
lexicographically ordered otherwise. Really, should pass these as named args when
calling, passing them by order is just asking for things to break.

Allow a loop to have both positive/negative condtions ('do ... while ...
until ...')

everge keyed lookups for guards/replacing, inspired by sendmail $()


In general, everge replacements need to be done by hand, instead of relying
upon replaceAll/appendReplacement to do it; all replacers will be indicated by $,
and escaped by \

server daemon mode for everge? send string to be processed/connect via a separate
mechanism to configure.

clformat flag to iterate backwards

allow 'shadow' imports from a namespace where any overlapping names aren't imported

language with both statement and expression if:


if a if b else c then d if e else f else if g then h else i if j else k
=
if (a if b else c) then
(d if e else f)
else
if g then
h
else
(i if j else k)

nil vs. null and the implications thereof


nil is the 'universal zero' value, or to be somewhat zen, it is the value
that signifies there is no value

null is like SQL null, where it indicates an unknown value; thus, this would
also be the error value.

This indicates that 'nil' would tend to disappear, while 'null' would tend to
propagate. In some circumstances, null can end up behaving like the 'Maybe' monad,
or perhaps an 'Optional'?

tagged indices: add ability to 'tag' an index to an array, indicating that it can
only be used with that particular array
syntax idea: array a of 5 tag b; int idx tag b;

Arrays can share tags; perhaps a way to restrict which indices can be tagged?
or not, could be a bad idea.

Some way to do easy conversion (maybe auto-conversions) between different


index tags

Could also allow tagging dict./map keys

three 'sorts' of data: tree-shaped, table-shaped, 'document'-shaped (XML/JSON et.


al. Don't recall the difference between this and 'tree' shaped)

XML literals: can be assigned to an arbitrary object, and will bind the fields
correctly (perhaps also invoke constructors in some places/times?)

clusters vs. packages: serve similar organizational purposes. However, a cluster is


also instantiable in some way, and generally provides a discrete piece/pieces of
functionality (Think sort of like a reified Facade pattern). When you import a
cluster, it is necessarily instantiated and bound to a name. Thus, a cluster can be
imported multiple times, while a package cannot

parametric multi-inheritance: can inherit from the same class multiple times, as
long as at least one parameter is distinct. Duplicate imports are either elided or
scoped to only be called by items from the same class instance.
discriminator member: any member of an object that specifies which of several
subtypes an object is. Mostly useful to allow an object to be auto-cast to the
relevant type when the discriminator is checked. Almost always, is an immutable
object drawn from a closed set (the prototypical enum, pretty much)

see libsixel for something kinda cool (also,


https://jirkasnotes.wordpress.com/2019/07/17/xterm-does-graphics-sort-of/)

Some ability to mark objects as 'persistant', which enables them to be easily saved
to some sort of backing store. Uses other markers like 'key' or 'constrained' to
control how things are persisted.
Three broad categories of properties: 'descriptive', which are inherent parts
of the object, read/write, and always stored; 'computed', which is determined from
descriptives, are read-only, and can be either stored or not stored.

some easy way to do a 'descending' foreach/use an index alongside values


between (prev/next) on for loops, invoked between loop items
'drop' - loop clause to not consider certain types of exceptional items
'apply-to-all' - some syntax to apply a foreach where it is obvious. Syntax
sort of looks like
String[] abc = ...; abc.{...};
'it' would be the pronoun which represents the item being iterated over

transitive member access - used on an iterable 'thing' to 'project' to a given


member; syntax would be '..>'
Bar[] bars = ...; Foo[] foos = bars..>foo;

could also use a type tag (int:* ?) to get all reachables ints. Not sure on
the utility, but it seems kind of interesting

fragment: a particular piece of code that may be loaded into memory. A fragment can
have multiple copies loaded at once, each called a 'connection' to the underlying
frament. Fragments are stored in 'containers' (read: libraries). All of the
fragments for a given process are grouped into a 'closure' (perhaps 'enclosure' to
reduce terminology confusion?). The code for a fragment is loaded once, and shared
across all processes; but data can either be shared or on a per-process basis. Each
section of a fragment is marked as containing either code or data.
Some proceses can use a function to load a private copy of the fragment. They
can do it multiple times, since the copy is private. Confusion may result if you
are not very careful about how you handle stateful code. They do still share code,
but are considered different processes for data.

Each fragment can have 3 marked symbols: the main symbol, the initialization
symbol, and the termination symbol. To be used as an application, a fragment must
have a main symbol. The initialization/termination symbols are called when the
fragment is loaded/unloaded

when using C++-style inheritance (multiple base objects), allow accessing different
bases by casting chains - doing the direct cast picks one in a deterministic, but
unspecified way

use '%' to convert a string into a pattern?

some sort of declaration to declare a type as conforming to an interface in a low-


overhead way?

allow 'conditional generics' ex: x is comparable if x.a is


allow named/default generics ex: X<A, B> is named A, B; X<A B, B C> is named A, B,
but the values are B and C

rethrows - only throws if a passed in lambda i9s throwing

'colored' functions - blue/red; red can only be called from red, is more annoying
to call in some way, and the syntax is different. Also, several important functions
are red. Think async. vs. sync

dependant threads
has an unordered input list
an ordered output list
can provide inputs at any time, in any order
must provide all inputs an output requires
instead of lists, use a DAG?
grabbing an output may block; attempting to grab an output when there is a
missing input may throw an error
add 'steps' with independant DAGs which can be switched to/queried

named booleans - essentially, two-value enums that can auto-cast to/from bool

pascal-style returns: each return value has name. And instead of using 'return',
you assign to the name

'declarator' typedef: typedef can go anywhere in type-sig ex:


typedef struct a b; struct a typedef b; struct typedef a b;

part of the compiler should be called the 'complier', so that you can have a
'complier' error

DelayOutputStream/DelayWriter - Variant of BufferedOutputStream/BufferedWriter


which will accumulate output until explicitly asked to release it
Hook this up to ReportWriter in some way?

Arbitrary base number - :60[2, 2, 2] // equivalent to 7,322 in base-10


follow a base with a list of numbers, and it will do the proper math. Some
syntax for multibase numbers would be interesting, as well as allowing component
numbers to be other bases. Some sort of way to do arbitrary exponentiation (see the
scientific notation for integers above) could be cool, though the syntax may be a
bit tricky

rational literals - where possible, use fractions instead of floating-point, to


enhance precision
built-in complex/dual numbers could be neat

interpolation control - some ways to control when and what certain things
interpolate might be good (perl adverbs?)

'bool'-ness of objects: some way to control whether an object evaluates as true, or


as false.

allow binding of expr-results from 'if'/'while' loop conditions to some sort of


variable: follow condition (in '(') with -> then the list of vars to bind

allow 'do ... while' style constructs to be written 'do while ...'

'take' as an l-value
should 'take' return what it was passed, the collection it is building, or
both? (mult-returns F.T.W)
'null' vs. 'fail'
essentially, 'fail' is a null that tracks where it came from, and will
provide that info when it was used in a way that would normally provoke an NPE

doing a test of whether a 'fail' is or isn't null will mark it as 'defused'


and note that site on the fail. This can be useful for identifying those who are
careful, but not careful enough

implicit 'gather'/'take'
any function can be marked as an implicit gatherer, which means that during
the execution of it, a special gather-scope is opened; this is used by functions
which are marked as 'implicit take' which will put their return values into such a
scope.

more usefully, a OO struct/class can be marked, which creates the scope when
the object is created, and makes it live whenever a member function is called

utility functions can be noted on the so-marked element to allow for things
such as taking other types, or resetting the gathered data

expression gather - swift 'function builder'

custom arrays - when creating an array, you can mark it as 'custom', allowing you
to either use a fixed enum, or a specified number range as indices. Useful when
indices have a meaning besides being indices.
note: unless you name a custom array type, it isn't implicitly compatible
with that of another custom array type, even if structurally identical (this also
applies to vars)

paragraph: data structure composed of a series of fixed-size lists plus a metric


function. will add items to a list until the capacity is exceeded, then will start
a new list. Has methods to do operations both over sublists and over total lists,
as well as a 'compact' function which attempts to reduce the number of sublists by
re-arranging things.

disjoint multiset: data structure that consists of a map of multisets plus a 'tag'
function. Inserting an item inserts it into the multiset for its tag. Has a series
of group operations.

disjoint struct: composed of a struct and a union. Contains the data for each
unioned option, but which are accessible are determined by the struct. Could be
useful to have one where struct is a constant, so as to minimize space usage.
ANother way would be to only init. a unioned item when it becomes active.

add ability to retrieve range/start/end for custom arrays

add index-range and index-set types (Range<Index> and RangeSet from Swift)

allow usage of offsets as indexes where applicable. generally, 'first' and 'last',
plus 'firstOf' and 'lastOf'; perhaps 'nthOf'. There are probably more

allow newlines to sub as commas. Most noticable when doing something with one expr.
per lines.

Identifiable - allows you to provide an object identity from a type that can have a
hashcode, without having to do so yourself

some intercal features could be interesting: semi-random statement execution,


statements which run once, or don't run the first time
operand overloading - whenever a given value is used, replace it with another

code paging - allow one set of code to be unloaded, and another to be loaded. May
need to be careful about unloading runnning code.

PostOffice: data structure which is a collection of queues which allow for complex
message handling. Includes things such as 'forwarding', 'return to sender' and
'multi-cast'

Warehouse: data structure for queueing with a different theme. The warehouse has a
particular set of items as 'inventory' and user can place orders to receive them.
Items can be 'back-ordered' if there are none/aren't enough in stock, and actions
can be triggered in that event, or if a certain item drops below a threshold. Also,
perhaps an ability to assemble certain item types together to form others?

OrderSet (OccurSet/OccurMap?) - data structure which is a collection of other


collections, but has an efficient way to get any collections that happen to contain
a specific item.

Note: See if any interesting ideas in the Javabeans spec/other JSRs

LimitQueue: queue with limited capacity (a LRU queue, pretty much). Overflow causes
the old items to be deleted (a ring-style buffer?)

reverse generics: generic return types, specified by the callee, not the caller.
Useful for dealing with collections and similar. Called 'opaque results' in Swift

subscript operators: have separate operator overloads for l-value/r-value


subscripts.

key paths: short-hand way to form lambdas which access a particular sub-object

conditional assignment: assign a value into a slot only if it isn't null

auto-levenshtein: a compiler option which will allow it to change unknown


identifiers into known identifiers with the closest edit distance, as long as it is
unambiguous which identifier you would be talking about.

${extract ...} - postfix text expressions ($extract{{<key>}{<str1>}{<str2>}


{<str3>}})
expands key & str1. str1 should be in the format '<key1> = <val1> <key2> =
<val2> ...'. searches str1 for the key that matches the provided one. If a matching
key is found, expand str2 with $value set to the found value. If not, expands str3

${extract{<number>}{<separator>}{<str1>}{<str2>}{<str3>}} - works similarly


to prev. extract form, but str1 is a separator delimited string, and it loads the
number field in str1,

${filter{<string>}{<delim>}{<cond>}} - string is a delim separated string.


This filters out any items that don't pass cond. $item is available in cond

${map{<string>}{<delim>}{<pat>}} - string is a delim separated string. For


each item, expands pat with $item set to the item

${reduce{<string>}{<delim>}{<pat>}} - string is a delim separated string.


Does a reduction on the list by applying pat, where $item is the current item, and
$value is the previous result
${sort {<string>}{<delim>}{<comparator>}{<key>}} - string is a delim
separated string. Values are sorted by comparator, where keys are formed by
expanding key with $item set to the list item.

lambda switch - switch which is passed a lambda. Each case statement provides a set
of arguments + return value. In the case of predicates, picks the first that evals
to true if not specified

inverse lambda switch - same idea as lambda switch, but the args are passed to the
switch, and each case has a lambda/return value.

rgens object rules - rules which produce an object instead of text. No real syntax
ideas though

DistributeIterator - Iterator which distributes retrieved items among a set of


child iterators.
CondenseIterator - Iterator which merges input from child iterators.
AsyncIterator (unsure on name) - iterator which starts a passed in task, providing
it with a single argument: a sink function which will cause the iterator to emit
any passed in value. Is there also a version which provides input in some way?
MirrorIterator - Iterator which mirrors input from one iterator to many other
iterators

Implicit member dereferencing - in places where it is obvious what class you are
talking about, you can use '.' to implicitly dereference such a class.

complex feed-in/feed-out patterns for DistributeIterator/CondenseIterator


allow CondenseIterator/DistributeIterator to run from a flat series, or from tuples

some sort of 'right-ward' assignment operator (=> perhap? though I believe there is
other stuff that wants to use that.)

slips - slips are nested lists, which will auto-flatten into any containing lists

AutoExtendList - Indexable list which auto-pads out to null if a large index is


used.
CyclicList - Indexable list which applies a modulo to any provided indices
EvenOddList - Indexable list where each element is a homogenous pair. Use a
positive index for one side, a negative index for the other.
EnumList - Indexable list using enum ordinals as indices
FlipFlop - predicate which behaves like '..' in Perl. Has a starting and and ending
condition, and returns a number. This is 0 is the starting condition hasn't been
met yet, or the one-based seq. number if it has. Has flags to include/exclude end-
point, and current range status can be checked
Counter - Data structure which supports increment/decrement. Can be backed by an
int, or by a string, to get the spreadsheet column 'A..Z..AA..ZZ' sort of thing

'continue' - block modifier which adds a block that is (almost) always executed
(except for 'break' mostly)

partial closing delimiters - when considering '(' and '((' as distinct delimiters,
consider allowing them to be partially closed, such that a single ')' will
terminate the specialness of '((' but leave you in a paren'd expression. An
interesting idea, but probably quite confusing and likely to do weirdness.

In everge, consider allowing something like $`, $& and $' from perl (text left
of/of/right of match)

Implement structured regex (see rx.txt and rx2.txt)


attempt to minimize (?:...) usage

EXMatcher - version of Java matcher w/ extra capabilities including: better


substitution and multi-match/list handling

check Error on CPAN


note that the 'layout justification' CLFormat directive may be a sublang (like
inflect) - check Perl 6 format for info?

'except' block - allows dynamic catching of errors. Given the exception, returns
the handler for that exception type.

ChunkIterator - iterator which groups items into chunks of a given size. Has a flag
that indicates whether getting an incomplete group is an error or not.

tied named arguments - way of specifying that some named arguments must/must not be
passed together
implied argumnents - some arguments imply that another argument has a particular
value/matches some particular predicate

java CLI arg parser

SkipIterator - Iterator which skips elements. Has an option on whether to skip more
that once.

WatchIterator - Iterator which calls a function whenever a value that matches a


predicate is obtained.

iterator which calls a function when exhausted.

Instead of having constructors with a standard name, have it be a marker of some


kind, to make people pay some modicum of attention and describe side effects in the
name

Class::Multimethods (CPAN module)

Adoption - add a parent class to another class

relevant type - Type whose value must be used at least once, similar to a linear
type type, which can only be used once

FlatMapIterator - an iterator which performs a flatmap operation. Perhaps a variant


which does it step-by-step recursively?

something like NSDocument and friends for Java


Swing undo tracking (NSUndoManage) and NSBrowser as well?

if that takes a condition block, instead of a statement

ugliest.app

SwallowIterator - Iterator which swallows any thrown exceptions from getting a


value (except the ones mandated by the iterator contract)

Artificer esolong - made up of various craftsmen which can perform varying tasks
upon an object

SelectionTrack - shunting yard variant whcih handles a facsimile of smalltalk-esque


syntax, including 'complex' selectors (which can have 'qualifiers' or subselectors)
allow specifying all arguments by name and positionally (inspired by PL/I or PL/1
preprocessor)
Find(int A, int D, int C) could be invoked like
Find(1, 2, 3)
Find B(2) C(3) A(1)
Find(1) C(3) B(2)
Find(?, 2, 3) A(1)

Specifying the same argument multiple times emits a diagnostic and causes the
last defn. to be taken
Arguments are evaluated from left to right

Each argument is bound to its name, and the value can be referenced from
other args by a $-prefixed name (use $$ to access the default value; use a leading
':' to access enclosing calls). It is an error to refer to a var. that doesn't have
a value specified yet (so only reference defaults of later args.)
A multiple-defined arg can refer to its previous values by including
[...] with the index after the $, but before the name

Use ? as an arg. standin when doing positional specifiers; this way, you can
get multiple var-args as long as only one is specified inline, and all of the other
are either not present, or omitted using a '?'
Finer point about this: specifying a ? only stands-in for a var-arg
param if it is passed in the first 'part' of the var-arg. Using a ? in the middle
of a var-arg is an error, so this also means that you can't specify a ? for the
argument following a var-arg. Perhaps this could be changed to say that a ?
terminates a var-arg and stands-in for the next argument. Not convinced either way.

Another point on var-args: they are considered to be an array when


referencing them, and specifying them multiple times will overwrite the array each
time. If you prefix the parameter name with a +, it will instead append it (it
might be nice if there was a prepend, but no sigil for that appears clear at the
moment)

regex-restricted keyword var-args: allows you to restrict both the name of any var-
arg, and the overall form (takes two regexen (... what?) one which applies to each
arg, and one which applies to a space sep. list) - allow a way to specify a value
regex and how that affects the name for simple types?
Not entirely sure what this is or where it came from, but it seems like it
could be useful.

add something to everge to specify repetition behavior.

NSStackView (collapsible panels) for Swing?


NSBrowser backed by TreeModel? Master/Detail controls?
An NSPredicate like thing?

everge/rgens GUI apps?

compound multi-assignment
c, c += c (not the same as) c, c = c + c
(is actually) c = c + c; c = c + c;
(however) a, b += c, d; (is) a = a + c; b = b + d;
(perhaps define an extension) a, b +=* c, d
(such that) a = a + c + d; b = b + c + d;

change rgens immediate <...> syntax to use selectors instead of indicator


characters; <?2> => ... <oneOutOf: 2> ... <chooseN: 2> (uncertain on exact details)
switch the non-immediate {...} to selectors as well
remove the '+'/'-' distinction from rule-names; handle that via an immediate
(<despace:> or something)
<decl:> for an inline declaration? or some other syntax?
allow specifying probabilities as dice. also, allow fractions like 1/10, 2/5
etc. May require a fixup pass to 'reuniversalize' functions (1/10, 2/5 -> 1/10,
4/10)
perhaps cut down on the usage of RGrammarBuilder; it feels a bit too stateful
to be easy to use

Allow selectors in [...]? Rule of thumb:


<...> - immediate; executes during parse time
{...} - execute normally, produce no output
[...] - execute normally, produce output

An easier way to invoke inflexion? also, integration of everge/clformat?

weighting for inline rules? may already be implemented, can't recall

use ':' in a rule-ref to refer to an internal rule (as long as it isn't


marked 'private' or some such thing)

more complex return types from case element generation? could allow getting a
rule from a rule, int math, and possibly other interesting things. Only when
explicitly declared though, using '->' on a rule header. Also, split header from
body if a header specific thing is noted

Kill the implicit usage of exported rules, either use a pragma


(import/import-all) to export things, or use explicit references. [rs!rule] (!
applies to the entire rule, use '(' to scope to a var-element). using [rs!] will
yield the default rule for that ruleset.

re-implement special-case handling for long-rules?

variable types: $ is scalar things, @ is arrayish things, & is templately


things (though should maybe be $&, since it refers to a single template). Could
borrow from Perl and say that % is a hash-like thing (can't call it hashish, that
is something rather different)

clformat: allow explicit item specification? item param/item ref param?

rgens: differentiate between array vars & rule vars?

expression hoisting: 'if def x = g(y) then x + 1 else 99' becomes


def x = g(y)
if x then x + 1 else 99

note that x doesn't go out of scope after the 'if' ends, and that 'g(y)' is
always evaluated.
This also works with function calls, though there are some fine points with
ensuring that function argument semantics follow the way that they'd be expected to
behave. so 'f(x, def x = g(y), x + 1)' equals
def temp = x (temp is a random name not bound)
def x = g(y)
f(temp, x, x + 1)
and order of evaluation is preserved in the way one might expect. also,
'f(def f = g, f(x))' equals
def temp = f
def f = g
temp(f, f(x))

Hoisting does work for boolean operations, but is treated specially when on
the right-hand side to preserve short-circuiting behaviors: 'g(y) or def x = 99'
becomes
g(y) or block
def x = 99
where 'x' goes out of scope as soon as the expression ends.

make everge stages explicit: ReplStage and things. Also, implement named stages.
Split ReplPair into parent/child classes for different types of pairs?
add history for stages which tracks the previous results
Complex pair results? bools and such.
Setting of default regex flags
Allow naming of pairs + complex stage routing; determine which inputs go to
which pairs?
Variant of /x from Perl?
Change input processing from a 'push' model to a 'pull' model, so that
interesting things can happen more easily
add CLFormat to everge?
split/join stages
'unique' matches (also, bundle state to match text? not quite sure what I
meant by that)
Allow specifying cyclic substitutions as well, both on general and on 'per-
regex' level
allow specifying alt. pair if guard fails
allow 'simple overlap' (attempt to match at each position in the output)
implement greedy mode for cyclic regexes (try until matching)
add control T (type/pairtype) for specifying special pair types (defaults to
find/replace all)
everge substages? add custom CLFormat directive in everge for applying a
stage/pair

SCL in everge/CLFormat/RGens?
Also, SCL in C? probably using FIFO/pipes or something
'spec' from IBM pipes in C?

allow 'otherwise' as subst. for 'else'

multiple input item lists for CLFormat? would need directive to switch lists as
well as copy/move items
also, one to send results to other input stream

allow '`' to be repeated zero or more times, with more '`' indicating a
directive is more uncommon/esoteric/specialized

add a way to 're-dispatch' to another directive; useful for generality (in


what cases? wish I'd noted them)

add a way to indicate that a UDF (user-defined function) takes a GroupDecree


as an argument (or perhaps one or more general Decrees)

write SPEC grammar? can RGens be made to only output valid programs?

add conditionalization for RGens rules

some analogue of CL 'LOOP' in java? not sure whether an explicit stack or recursion
would be more useful; however, it should be a builder-style interface
version of RGens with an explicit stack for evaluation instead of recursion?

java preprocessor for smalltalk-style message sends/collection literals? seems a


lot of work for uncertain benefit.

use !-> for a non-auto-return quicklambda.

allow 'places' (lvalues) where possible


add explicit 'xor' operator

unary spread - +...[1, 2, 3] == [+1, +2, +3]

overload '/' on strings to be 'split'

clonewith operator - clone/extend map:


{a: 1, b: 2} #=> {a: 3, c: 1} yields {a: 3, b: 2, c: 1} (LHS is inscope for
RHS)

use prefix 'do' or postfix '!' to call a no-arg function


do a!b!c => a().b().c()

bracket a name with '`' to call it inline as a binary function.


1 `add` 2 => add(1, 2)

specify an expr as a default arg to perform a mutation of the passed-in arg.

'provide' - expression which exports a given series of names from a scope


provide (x, y, z) {a = 1; x = a; y = 2; z = a + y} puts x, y and z in-scope,
but hides A.

This is more useful when you start using local functions with internal state
that you want to keep around, but don't want to allow the world to mess with. Think
sort of a inverse-closure mechanism. Instead of specifying what values you wish to
capture, you specify what values you want to expose, and all of the others are
captured.

for ranges, 'to' includes the end-point, 'til' does not

when used as an expression, loops auto-collect their results into a list. Follow
the loop keyword with : to perform a mapping on the list, and with ! to perform a
reduction; these can be nested and intermixed

generate ... [from ...] [until ...] by ... - operator expression for forming a
generator. The initial ... is the name of the value inside the expression

reduce ... from ... [with ...] by ...


operator expression for consuming a generator. Can specify more val. names in
both to get additional state/handle additional sources (use ';' to separate sources
from each other)

.{ and .. - .{ starts an object-dispatch context with the LHS; while within this
context, .. will invoke a method/property on said object. .{ returns a list, and
can be treated with a loop (can use '!' and ':' for post-processing)
Use ..{, and it will just return the LHS, not the context results

begin/end, {/} and is:/end all serve as interchangable block markers.

unary % defines chance a statement is executed; if over 100%, a statement may be


executed multiple times
Can also be applied to blocks to work in the obvious way.

some way to do 'fusion' of nested loops in CL LOOP - basically, have a 'forest' of


loop clauses, with each tree being stepped once per iteration

friend/acquaintance - friends can see private properties/methods, acquaintances can


only see methods

container classes
container class ... (<type params>) is:
with <type-param> as <type-constraint>
interesting syntax for specifying type params to things

lest clause - terminate the function unless a particular exception is thrown

allow specifying 'catch' blocks independantly, then binding them to 'try' blocks by
name

use &{ or &( to set a variable to a lazily evaluated block

some operator which does implicit line continuation until a blank line is read

'half' syntax for format/printf


"text ${val-name directive/specifier}" where val-name comes from a map
argument

BJC-utils function using var-args to auto-create a map

%>% / %<% as function compose operator; =>> as the reversed assignment operator
/\ as alias for &&
\/ as alias for ||
|+| as concatenation
@@ to attach a tag to a type, @@? to check for a tag, -@@ to remove a tag
== defines equality among everything, === defines equality only between
things that could possibly be equal

node-list/euler-tour/link-cut tree: inefficient, but guaranteed to stay treeish


also, splay trees
visitors/visitor chaining for trees?

parser combinator operators

consumptive arguments - mark passed in value as no-longer-in-scope

everge/clformat/etc input/output streams: TransformStream/TransformWriter?

allow construction of standalone arg-blocks


InterCAL stash/remember for variables
stream/reader which universalizes newlines; also, one which tracks line/char/page#

use += to append, ++= for appendAll

allow overloading " " operator for how to handle two adjoining values

Allow array/map literals to take postfix !/:

implement perl-style split, whcih returns strings and captures from delims (as an
iterator)
to fully satisfy the complexity requirement, provide SMTP/POP/IMAP built-in :)
lexically scoped stateful modules + perl autouse to create a 'fun' surprise
perl autouse loads a module for the first time when you call one of the
functions in it

full unicode char-name expressions - \U

'branch' to replace current stack-top with another (shows up as '... -> ...' in a
stack trace) as well as return-type conversion syntax

rgens - use <:, [: or {: to introduce selector context

format directive for localizable string

allow switch early-exit/fallthrough/continue - ;;/;&/;;& from bash?

brace-expansion directive? also param expansion?


heredocs: << is normal, <<- strips the margins, <<< interpolates (should <<<-
do both stripping and interpolation?)

techos - implement VMS style qualifiers. May need a general arg-parsing rewrite,
moving away from getopt & friends to hand-written code. Also, a getopt with
supported qualifiers would be neat (on both args & nonargs) using either --- or
':'; also, sub-commands

create a CLI tester for CLFormat/RGens/everge


allow reconfiguring CLFormat directive maps
~= to set format vars, &followed by name/number to ref items, && to consume
current one
allow marking items as 'consumed', which prevents them from being directly
iterated over

implement cursor/'hand' types - include the 'consume' ability mentioned above.

add ability for directives to read other directives - hard-coding certain directive
parameters/modifiers?

forth-style block editor for SCL?


base-85 strings (<~ and ~>)
nest/unnest to enter SCL substacks
/ for 'quote-symbol', // for 'exec-symbol'? or "'" and "`" (single
quote/grave)
operators to explode/compact substacks
SCL ret-composite by default? e.g
[1 2] dup leaves two refs to the same array (or perhaps, one ref, then
the actual array, since we don't really have a notion of 'heap' vs. 'stack'
allocated objects that would necessitate using two refs)
use 'weaken' to convert a ref. to a weak-ref
'pick' to copy a stack element by index - 'fn' combinator: pop N items into a
temporary stack, reverse main stack, push N items

condMap :: (A -> Bool) -> (A -> B) -> (B -> Bool) -> (B -> C) -> A -> Either A C
:: (A -> Bool) -> (A -> B) -> (A -> Bool) -> (A -> C) -> A -> Maybe
Either A C

implement lowercase/uppercase diff. for custom radix numbers

saturated/unsaturated stores (xoomonk) - Tables which refer to undef. keys are


'unsaturated' and are only fully evaluated once all of the missing keys have been
provided
Store<K, V> - addDeferred(K key, BiFunction<Store<K, V>, K, V> valueFunc,
K... depends)

toString takes n arguments: the style, and then any style args

'panfix' notation - op arg1 op arg2 op

variables named by a regex: must use different but equivalent (which is guaranteed
to be doable, though not in linear time I believe) regexen to refer to it

implement SAM-type structural regex (ACME editor and that sort of thing) in Java

CCL test input format: source starts with '|', input with w/ '<==' and output with
'==>' (see also, Falderal)
in Troff
format, .TS_SRC, .TS_IN, .TS_OUT; .TS_FILE, .TS_PROGRAM, .TS_TESTFILE?

allow specifying alt. entrypoints ('entry') with own args. (can also use own
return, though that may cause runtime error in some cases.)
use 'cancel' to re-init static static state. Note that calling 'cancel' on a
procedure that is further up in your call-stack is a good way to cause interesting
things to happen,

Implement a toy COBOL w/ some functional/generic style commands (LAMBDA/SPECIALIZE)

use 'call ... on ...' instead of invoke in COBOL? use 'CHAIN' for method chaining.
complex redefines: fields with a bound function
format directives inspired by string/unstring?

clformat split directive

paramorphism of fold (including snapshots) - though I can never recall what all of
the various -morphisms do; wish they had more easily memorable names

CLFormat equivalent of Perl \x (~")


rgens - affix grammars?
Java PredList - list which can only contain elements that match a predicate. Unsure
as to whether the predicate is exclusively local, or if it would make sense to have
a global procedure
scientific notation for integers (see above a bit)
use '///' for regexes that auto-have \x enabled
refer to mutexes as bottlenecks?
simple given/when/then testing in Java
Call a Queue a SpaceTimeDecoupler
use overloaded < and > for semi-custom inline ops (wish I could recall more of the
details for this...)
add 'when' clause to catch blocks to only catch exceptions that pass a certain
predicate (fun with side-effects -_-)
use .+ to call all compatible variants of a function
'temporal spread' - instead of performing the normal expansion of a list that a
spread does, instead calls the function once per each item in the list, auto-
converting the result into a list. Preliminary syntax is to prefix an argument with
**. If you specify multiple arguments, they will be called from left to right. To
'match up' certain arguments, put text in between the two *s.
Interacts in an interesting way with composed function calls instead of
nested ones. If you nest it, it will repeat the nested call. If you do it with a
composed call (using |> or other piping operators) the whole call will be repeated,
not just the nested part
DynamicMap - A map where the keys can be bound to one of 3 things: a finite value,
a lazy computation, or a dynamic function. Note that elements that result from a
dynamic function or from a lazy computation that hasn't yet been evaluated will not
be considered to be 'in' the map for the purpose of contains or other such
functions
There could also be some support for dynamic keys, but those would be more
problematic for performance, especially if you wanted to do truly dynamic keys, not
just lazily evaluated ones
in RGens, considering using '/' to allow for easy accessing of nested vars, instead
of futzing with [] and {} and the like

use %% to check divisibility (a % b == 0)


'+' on lambdas to compose them (for lambdas with returns) or sequence them (for
lambdas without returns)
use +/- to add/remove lambdas
use / with a list & lambda to do filtering; and - to remove from a list
(&) as set intersection, (*) as weight-set multiply (intersection + multiply
corresponding weights)
(|) as set union, with (+) as weight-set add
(-) as set difference, with (^) as symmetric set difference ( (a(-)b) (|) (b(-)a) )
range operators from Perl 6 (../..^/etc)
XML literals (plus XSD/XQuery bindings :D)
'before'/'after' as abbreviations for ordering
=:= for 'container' equality (shared value)
=~= as approximate equality (delta for floating points, levenshtein for strings)
(<=)/(<) as subset of/strict subset of
(>=)/(>) as superset/strict superset of
^^ for 'xor' (only one true value; short-circuits as soon as an additional true
value is eval'd)
::= to create a read-only reference to a value
supply/emit for an async gather/take
use 'start' on a block to launch it async
'then' as a general block sequencer
'sift' - remove items randomly from a list until it hits a certain target size
'squish' - given a binary operator, randomly use it to merge list items until
hitting a certain target size
'translate' - given a map, convert a list of map keys into a list of map values

have C# style partial classes, but allow each class to specify who it inherits from
independently. Can result in C++-like 'diamond' problem if there is a shared base
somewhere (each partial class prefers the base it explicitly inherits from; use
'virtual' on the inheritance to say not to include duplicate bases)

In MI, classes to the right override members in classes to the left. Can have
interesting interactions with the C++-style super-constructor calls where each
constructor can only reference initalized members (those to the left)

Allow using 'ancestor' to define a ref. to a base class: ex.


class a {}; class b: a {}; class c : a {}; class d: b, c {};
class e: a, d {
ancestor a base1; // Refers to directly inherited 'a' object
ancestor d::c::a base2; // Refers to the 'a' object inherited from d
}

call the 'sink' meta-function when a value is ignored, or used in a context where
it's value couldn't possibly be checked (ex: in a, b; the value 'a' is sunk)
(parameters to functions can be flagged as 'nonsink' to indicate that a value being
passed there doesn't count)
This could be helpful with things like C++ temporary creation/destruction
where it isn't clear when a particular value is created/destroyed.

use the 'real' modifier on a function to specify that it is non-virtual


use 'hyper-virtual' to allow invoking new overloads of a virtual function
(perhaps only those that are 'more specific'/'less specific') (maybe 'paravirtual';
use '.@' for a call)

'hyper'/'race' for a parallel for ('race' doesn't enforce ordering)


use '%' with a list & a lambda to partition a list (result determined by lambda
return type)
promises are either planned, kept or broken (promises can have 'vows', which allow
only those that have the vow to keep/break promises)
something involving CompletionStages from Java? CountedCompleter could also be
neat, in addition to Phaser

sandwich based esolang: various async computations produce sandwich parts, and once
you have all the parts for a sandwich, a sandwich is produced
Ingredients go into tagged queues
Each sandwich has a tag, but can also use untagged things
Ingredients can be made up of other ingredients
(Inspired by Raku concurrency, also while hungry)

'gulp' block auto-catches exceptions and discards them


'import localization' such that following is valid:
import-local java
import io.* // is equivalent to java.io.*
'deep import' - import a package, and all of its sub-packages
allow bash-style brace expansion in imports
fun with "\x": "\x09GOOD" != "\x09BAD". The trick here is that 'B' is a valid
hexadecimal digit, while G is not. So, B and A are merged into the bit there.
multi-parameter [] overloads
NestingList (already implemented this one at least in part)

duckMap :: (NestList A -> Bool) -> (A -> B) -> (NestList A -> NestList B) ->
NestList A -> NestList B
Semi-recursively transforms the list. Applies the transform to each scalar
element, and the predicate to each list element. If the predicate returns true, the
list is recursively mapped. If false, the list map is applied

WordProper - BufferStack based copy/paste. ctrl-shift-{c, v, x} to do so without


changing the stack. Scripting for wordproper? Status bar. Customizable tabs/tabs to
spaces. font selection (JFontChooser). Color selection/sort linewrap (after space)

use '@n>' to note an intercal style belongs-to relationship in a type (n is the


assoc. number)
use 'associate'/'dissociate' in code to add/remove a belongs-to relationship
use '@/pat/>' to indicate a type for all associations that match regex
patterns.
Append a ? to indicate an optional association (though patterns are
automatically marked as optional)
Use '<n@' as a unary prefix to get value; and append a '?' to check
association. (n is number/string)
Use '<n@>' to indicate a recursive belongs-to 'n' levels back

intercal style OOP


add 'lectures' (methods) to classes, 'textbooks' (instance properties) to
classes
'handouts' (method-local vars) to lectures, either generically, or class by
class
'seminars' or nested classes
'materials' (static vars) can be added to classes and lectures (both
generically, and class-by-class)
'skills'' can be either taught or required by classes/lectures (taking a
lecture teaches you its associated skills)
'students' 'enroll' either by class, or by specifying the lectures they want
to take/skills they want to learn. They can be enrolled in multiple classes, as
long as they are non-conflicting
When graduating clasess, gain skills from it
Skills can have properties/methods?
'knowledge' is props/methods associated to student
textbooks/handouts can have editions (versions for handoffs) to prevent
sharing

add ability to free/deepfreeze a class to mark it as immutable, and


'thaw'/'deepthaw' to make them mutable once more (the 'deep' version is recursive).
Items can be marked as 'hot'/'cold' to prevent them from being frozen/unfrozen.
Mark them as 'very hot'/'very cold' to make attempting to do so an error.

NonEmptyList in Java?
implement tag/goto tag CLFormat directive
NonNull holder (to the extent that makes sense)
Controls combinators for lambda
Spreadsheet type? (!! for cell ref)
ExhaustMultimap - get also removes a copy
RestrictedType<I, O> { bool meets(I in); Optional<O> form(I in); I deform(O in)} //
Subset types
'int fractions' (two naturals, N & M where value if n - m; (n1, n2) ~ (n2, m2) iff
n1 + m2 = n2 + m1)
<:</>:> - subtype of/supertype of
=:= - type equality
one DAO per DB table, one Repository per data type
groupBy multiple categories (see Perl categorize)
RotorIterator (perl 6 rotor)
invert on pair
abstract methods on enums?
different mouse buttons trigger different menus
evented collections/iterators (use sep. dispatch thread)
- eventful logging? (easy enable/disable emission)
java EventHandler/java.beans package and friends (BeanBox)
clig - commandline interface generator
use 'given' to implicitize a value; use 'summon' to look for a particular implicit
value
zip iteraotr
IHolder replicate (presumably, Perl related)
regexes + bool functions (brzozwski)
Write thing tracking books/papers and reading status/notes
PartialIterator: ex from (1, 2, 3) yield (1), (1, 2), (1, 2, 3)
use :=> to attach an implicit function parameter
call class as function to call the constructor
convolve(f, g)(t) = integral(f(X)g(t-X)dX)
JCLShell - add network connection/pipes/FIFO (custom UNIT types)
IEBGENER/IEBPTPCH
groupCube :: (a -> [String]) -> [([Maybe String], [a])]
JQuery style filter/end in java
UniquePredicate - predicate which tracks what it has been called with (set exists +
put)
=^ for startsWith, =$ for endsWith
tagMap :: (a -> [b]) -> [a] -> Map A [B]
biPredMap :: (a -> bool) -> (a -> b) -> (a -> c) -> [a] -> [Either B C] // picks
function using predicate
Expected<E, T extends Throwable> extends Either <E, T>
Ithkuil (conlang)
Allow overriding ++/--, +=/-= and +/- independantly
Explicit vs. implicit lambda capture, capture by val/capture by ref
Use @: for attribute/annotation declarator
?:= for 'assign if not null'
filterMap/distill
Java mutable string (StringBuilder/string_view)
retain as inverse for filter
Abbreviated syntax for passing matching vars for keyword arguments (ex: f(a) ->
f(a=) -> f(a=a))
add receive-once listeners
java IntMap
Holder that stores previous values
java version of compute for HashMaps that has sep. function to vivify all keys
operator precedence/tree-rewrites

You might also like