Transcribe 2
Transcribe 2
'forall' loop
forall x = 1:5 where x + 1 == x -1
* executes for everything initally specified that satisfies the where
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
}
hook f g x = x 'f' (g x)
fork f g h x = (f x) 'g' (h x)
convolution
c(k) = sum(i+j = k): a(i) * b(j)
'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
adverbs
':' followed by a name, changes the behaviour of the previous
operator/expression bit
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.
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
ASCII 14-15
Shift In/Out
'entangled' variables
Declared as a function/variable pair. Calling the function updates the
variable from anywhere.
checkpointable
checkpoint() : void -> boolean
rollback() : void -> boolean
commit() : void -> boolean
commitAll() : void -> boolean
rollbackAll() : void -> boolean
inCheckpoint() : void -> boolean
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
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?
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.
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.
? Placeholder
When using a function in a context where only one arg is expected to go,
indicates where it should go
In block literals passed as arguments to something, use :: to access args from the
parent.
relative backreferences?
subroutine recursion
Attempt to match a particular subgroup
(?| - Branch Reset Group: Each alternative starts at the same subgroup number
(?> - Atomic Match: Upon success, throw away any backtracking points created inside
the group
(?< - 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.
In a balanced group, follow a group name to only succeed if the captured value
matches a given regex
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
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.
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
class Holder<ContainedType> {
private ContainedType value;
>>/<< as function composition operators e.g: f >> f >> h = h(g(f(x))) or f << g <<
h = f(g(h(x)))
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
rewritefs
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: ...; ...} ...};
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
proto-set primary
diexp diexp
dicexp dicexp
proto-set secondary
diexp diexp
dicexp dicexp
proto-set tag
diexp string diexp
dicexp string dicexp
proto-set repl
dicexp diexp diexp
dicexp diexp dicexp
proto-set predicizize
(-> bool int) dicexp diexp
(-> bool int) dicexp dicexp
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.
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.
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.
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 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
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
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.
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.
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.
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.
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.
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
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.
talter - 'thread alter' - Alters an execution label only for a given thread,
which shadows any non-thread-local changes
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?
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.)
try and do something like 'INSPECT' from COBOL (see if it can be generalized in
some way; ref. p303)
also, 'UNSTRING' (ref. p392)
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
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.
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
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'
@export
def test {
var list DemoList<int> = [1, 2, 3]
var map DemoMap<int, int> = {1: 2, 3: 4}
}
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> = []
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
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.
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
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
change ?: to ?? !!
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.
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.
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.
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.
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;
}
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
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.
for the feed/backfeed operators, allow a way to specify which arg. is filled with
the fed value
'redo' in a loop to restart the current iteration, 'retry' to restart the entire
loop.
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 :*:
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.
Allow a loop to have both positive/negative condtions ('do ... while ...
until ...')
server daemon mode for everge? send string to be processed/connect via a separate
mechanism to configure.
allow 'shadow' imports from a namespace where any overlapping names aren't imported
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.
XML literals: can be assigned to an arbitrary object, and will bind the fields
correctly (perhaps also invoke constructors in some places/times?)
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)
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.
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
'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
part of the compiler should be called the 'complier', so that you can have a
'complier' error
interpolation control - some ways to control when and what certain things
interpolate might be good (perl adverbs?)
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
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
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)
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 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
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?
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
key paths: short-hand way to form lambdas which access a particular sub-object
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
Implicit member dereferencing - in places where it is obvious what class you are
talking about, you can use '.' to implicitly dereference such a class.
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
'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)
'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
SkipIterator - Iterator which skips elements. Has an option on whether to skip more
that once.
relevant type - Type whose value must be used at least once, similar to a linear
type type, which can only be used once
ugliest.app
Artificer esolong - made up of various craftsmen which can perform varying tasks
upon an object
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.
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.
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;
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
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?
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
write SPEC grammar? can RGens be made to only output valid programs?
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?
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.
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
.{ 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
container classes
container class ... (<type params>) is:
with <type-param> as <type-constraint>
interesting syntax for specifying type params to things
allow specifying 'catch' blocks independantly, then binding them to 'try' blocks by
name
some operator which does implicit line continuation until a blank line is read
%>% / %<% 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
allow overloading " " operator for how to handle two adjoining values
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
'branch' to replace current stack-top with another (shows up as '... -> ...' in a
stack trace) as well as return-type conversion syntax
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
add ability for directives to read other directives - hard-coding certain directive
parameters/modifiers?
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
toString takes n arguments: the style, and then any style args
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,
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?
paramorphism of fold (including snapshots) - though I can never recall what all of
the various -morphisms do; wish they had more easily memorable names
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)
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.
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)
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
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