Thanks to visit codestin.com
Credit goes to github.com

Skip to content

nick-chandoke/codenotes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

it’s code notes!

and can you believe it! wow! so they are notes: unprofessional, only somewhat organized, often judgemental, and probably unfairly so sometimes. i might get ahead of myself sometimes, and certainly many of the notes are "ranty". not a tutorial, nor a book. i put them here in hopes that you’ll find good information here. i will eventually, and i would were all of my needs satisfied, make them into a polished, computable book, and create a repository for a computing device that makes coding ideal. i also want to write a "tour of programming" document discussing where i began as a programmer and all that i’ve learned and considered. it’ll basically be discussing why each programming paradigm fails and why only a natural, messy "paradigm" works ideally, much akin to discussing why we need fractals or a new mathematics to discuss turbulence, as euclidean concepts are only approximations, naïve simplicities that are as easy as they are incapable.

Note
just-use-lists.adoc is deprecated. it was to favor sexps over structs, which is correct, but inferior to relations/predicates, which are necessarily the least constrained structure.
  • stateful servers, not "alloc-do-free" aka reductionist, or "dead" programs. they should be modifiable & debuggable as they run, never crashing, but halting then returning execution to an earlier point. being a server naturally generalizes to the erlang model. using predicates (like prolog) makes this easy. prolog progarms are queryable db’s. "reductionist" programs are defined by a structure to traverse (ast or stack) and the traversal is predefined. ast langs are depth-first traversals of structures rooted (for the stack, rooting means that the stack has a fixed initial state, namely empty) at main, after any top-level statements (e.g. definitions of constants or functions) have been processed.

    • in a reductionist model, unbound variables assume the empty value (usually denoted f or nil, supposed to correspond to ∅ or ⊥), whereas in the logical model, they assume the set of everything.

update, may 9 2025: the rest of the document is idk some stuff that i wrote before. looks like some more ranting on declarative vs reductionist models. uhhhhh w/e; i’ll consider it later.

interpretations

i prefer to think of reductionist programs as paths through an unknown graph, and declarative programs as an infinitely sized undirected graph; queries identify path(s) through the graph. an undirected edge is equal to a bidirectional edge; in the declarative model, defining a relation can be interpreted as simultaneously defining a morphism and its dual. for example, the xor relation:

xor(0,0,0).
xor(0,1,1).
xor(1,0,1).
xor(1,1,0).
% example query: ?- xor(a, 1, not a) :- xor(a, 1, c) = {a=0,c=1 ; a=1,c=0}. a & c are implicitly universally qualified
create table xor(a integer, b integer, c integer);
insert into xor values(0,0,0),(0,1,1),(1,0,1),(1,1,0);
-- example query: select a,b from xor where b=1 and c is not a -- returns {(0,1),(1,0)}

we see that "outputs" determine [imply] "inputs" and vice versa. in fact, being ternary, there’s no implicit/natural partition into inputs & outputs. in fact, even if we partition into Z × Z → Z, xor is commutative! we cannot generally distinguish one input from another. constraining any subset of attributes constrains the other two, and instantiating (the ultimate variety of specification (meaning to endow with a predicate)) any two [to a literal datum] specifies the other attribute.

Note
sql uses relations (of literal data), not logical variables & constraints! it cannot e.g. optimize away a predicate that’s guaranteed to be false. perhaps prolog cannot, either; i’m unsure. perhaps that’s what an sat/smt solver would do that prolog does not. regardless, being declarative does not imply being logical! indeed, sql is reductionist & declarative! its queries are traversals of data which will eventually halt for non-virtual tables (tables literally represented by data literals) but will traverse tables, making sql little more than an efficient search/filter on b-trees. sql variables are not abstract symbols; they’re syntax that symbolizes to column of literal data, just like a variable in apl symbolizes an array of literal data, or how a symbol in a non-array lang symbolizes a literal datum. the xor example didn’t feature general horn clauses of abstract symbols e.g ancestor(X,Z) :- parent(X,Z) ancestor(Y,Z).. at least hypothetically prolog could reduce traversals e.g. 0*sum(λx. (x + 1)) to 0 without traversal whereas sql, per its design, not necessarily reflective of codd’s relational algebra, would traverse a table, accumulating a result table of increments, then toss it to return a table with a single 0 cell. prolog uses predicates whereas sql uses sets. they’re isomorphic algebras, but predicates are a much more efficient encoding, enabling things like x, which, being an unbound [unconstrained] symbol, refers to the entire universe of values, which is obviously not expressable in a strict-eval lang. such sets are expressable only by predicates, so we may as well use predicates directly. their algebras are both rings anyway; what more could we care to know?
in practice

programs are abstract, constrained systems. as a programmer, your sole job is to identify constraints i.e. identify the logically consistent program most similar to the spec given by you or a client. relation ≡ constraint. the simplest constraint on things is for them to belong to a common set. in the relational/declarative models, sets are named e.g. sql table names or prolog predicate names. more complex relations are relations of relations. programs are relations just as mathematical expressions are relations of arbitrary existentially or universally qualified symbols e.g. ∀a b c. a+b/c where ` & `/` are not qualified but are still arbitrary; their definition is given by predicates [axioms] that they must match, much like how AND & OR in boolean algebra are defined over existentially and/or universally qualified symbols. btw, as a prolog predicate, `a+b/c` is `/(a,b,o). +(a,b,o). /((a,b,x),c,y) where all but x & y are specified; the output will be {x=?,y=?}. obviously similar to sexps. in sql it’d be create table add(a,b,x); create table div(c,d,y); select y from div where c = (select x from add where a = $1 and b = $2) and d = $3;, except that add & div must be virtual tables, since they contain an infinite number of values (this can be done in sql or c.) any programming beyond that is merely identifying convenient encodings for given relations.

it’s no more sensible to define a reduction than a main function. like how it’s sensible to define functions then use them in a repl, so it’s more sensible to define relations instead of computations over them; the queries should be done on-demand in a repl.

encodings & languages as traversals over structure

structure contains the same information as encoding and is a synonym with relation (isomorphic with predicates) & form. an encoding’s efficiency is its lack of redundancy. for example, 2 is an efficient encoding of {x | x ≥ 2}, encodings require interpretation; thus they’re syntax. this is true regardless of whether the encoding is textual or else. thus syntax is a nonsense; it has no certain meaning more specific than encoding. ultimately all data encode some structure and can be interpreted into some idea. the structure is intrinsic whereas the interpretation is subjective. as bit-twiddling.adoc describes, encodings permitting multiple interpretations can be extremely elegant, terse, & efficient.

additional structure can be added for efficiency; generality and specificity are mutually exclusive, and generality generally implies less efficient traversals because more possibilities must be considered so more computation does to deciding/determining. for example, given that we want to sum elements of a set, a list is a more efficient encoding (both textually and literally in memory) than a graph since the graph can express data more general than a list. especially in a language like lisp which is designed to traverse lists, a list is most efficient since it’s natural to lisp’s evaluation model. these are easy assertions because the sum of a list is no less efficient to calculate (at least on a single thread) than the sum of a set.

TODO: programs as general traversal: a loop & state.

the nonsense & truth of metaprogrammability

as mentioned in the prior section (on encodings):

  1. all is information, encoding, data, related thusly: data is encoded information.

  2. syntax is nonsense

if syntax is nonsense, then so are macros—syntax endomorphisms. without syntax, there is no distinction between "code & data"; all is data[1], and code is a synonym for syntax, so there’s no code; again, their definition’s fallacy is that there exists a certain property that specifies syntax beyond other data, but truly that does not exist. so rather than "code," reason about encoded data/information, which may represent relations [with other information].


[1] proof: by definition, all is information. information, being abstract, must be represented physically to exist physically. by definition, data & encoding are the matter & form that represent information. however, there may be encodings with abstract data, which may implicitly refer to sets of literal data.

About

really code & math

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published