it's odd how many programs i use lately have this weird thing where they start up, and then after a second or so they "reboot". am i the only one noticing this?
the facebook app on android did it first.
then i noticed it in SDL2 after the window has been set up, when i request the render surface.
now vscode did it after i opened the console.
it's a quite irritating trend. and it feels weird, like the phone clicking right after you begin a call.
wrote a simple runner for a 20 bit state machine which gets 6 bits of input. in addition there's a render function that gets 20 bits of state and outputs a 16x16 4bit sprite index, and a sprite-map function that maps 16 indices to 8x8 sprites using the PICO-8 palette.
the whole thing works. now the next challenge is to write a game with just 20 bits of memory available.
Hypothetically, the simplest perfectly parallel program requiring no operations or instructions at all is a look-up table. The bigger the table, the larger input and output can be. A table of 2^(N+M) bits maps a 2^N bit index to a 2^M bit value.
The main jobs are then figuring out
(1) how to populate the table
(2) what storage format to use
(3) how to access it randomly
(4) how to verify the table
Above description is a problem shaped in the form of a solution, i.e. an abstraction. This LUT as an abstraction has these combined benefits over other abstractions:
It is an algebraic object
There are no other dichotomies or types
Program and data are the same
It has a canonical rectangular shape of fixed size
Reordering problems in programming are interesting: Your output doesn't have the same order as your input.
(A) You read in the input sequentially, your opening move is fopen(). The output order differs. Sometimes it's almost parallel, but then flipped here and there (read-ahead). sometimes it's completely backwards. Every time you use some form of buffering to make up for that - in severe cases, this buffer becomes a polymorphic data structure.
(B) You read in the input in parallel. Your opening move is mmap(). Now the game changes. You often build some form of divide-and-conquer indexing structure. If there is sequential context, then your data is in ambiguous state and you need some form of convolution. Sometimes you gather, sometimes you scatter. Your intermediate buffers mostly look like layered pyramids.
The problem with us humans is that we can't help thinking in anything but one dimension, one foot in front of the other, when work is concerned. And hence our programming models keep looking like (A). Our texts are 1D. Our graph topology is visited in 1D. Very often, input structures are deliberately shaped for serial processing - like humans read. And once they're shaped for parallel processing, they become difficult to manage. I wonder if we're not hitting some hard cognitive wall here.
orenc thtesodo goami rna
orenc thtesodn goami roa
orenc thterodn goami soa
orenc thte odn goamirsoa
orenc thte idn goamorsoa
or nc thteeidn goamorsoa
or nc thtgeidn ooamorsea
or nc thegeidn ooamorsta
or na thegeidn oocmorsta
or a thegeidnnoocmorsta
or a thegeimnnoocdorsta
r aothegeimnnoocdorsta
r aodhegeimnnooctorsta
r aodhegeimnnoocaorstt
r acdhegeimnnoooaorstt
r acdeeghimnnoooaorstt
r aacdeeghimnnooo orstt
aacdeeghimnnooororstt
aacdeeghimnnoooorrstt
aacdeeghimnnoooorrstt
sacdeeghimnnoooorratt
a sacdeeghimnnoooorr tt
a satdeeghimnnoooorr tc
c a satdeeghimnnoooorr t
c a s tdeeghimnnoooorr ta
coa s tdeeghimnno oorr ta
coaos tdeeghimnno o rr ta
coaos tdeeahimnno o rr tg
coaos td eahimnno o rretg
coaos td erhimnno o raetg
coaos to erhimnno d raetg
chaos to roimnno deraetg
chaos to roemnno deraitg
chaos to rdemtno oeraing
chaos to ordemtno eraing
chaos to ordertao emning
chaos to ordertmo eaning
chaos to order to meaning
interesting problem: progressively mapping a cosmically high number of unique strings of arbitrary length to an ordered set so that we can assign an index to each string, extract a substring from each index, and filter strings not in the set.
evidently, this approach requires compression. the compressed result is functionally equivalent to a regular expression, or a schema validation system.
been experimenting yesterday with a 1-bit trie, and that made clearer to me how tries and hashmaps relate to interpretation and compilation.
in an interpreter, each instruction only takes single arguments and outputs single arguments to produce definite results.
compilers however attempt to partially specialize functions, which we typically implement using types; but what we're really doing is use types as an approximation for the set of all possible values that could go into a function.