This commit is contained in:
Alexander 2025-06-09 00:20:26 -04:00
parent dbadcf267e
commit 66af302e2d
115 changed files with 721 additions and 278 deletions

View file

@ -0,0 +1,550 @@
<h1 id="programming-language-general-purpose-1">Overview of the GP1 Programming Language</h1>
<h2 id="description">Description</h2>
<p>GP1 is a statically typed, multi-paradigm programming language with
an emphasis on brevity and explicitness. It provides both value and
reference types, as well as higher-order functions and first-class
support for many common programming patterns.</p><p>This document serves as a quick, informal reference for developers of GP1 (or anyone who's curious).</p>
<h2 id="variables-and-constants">Variables and Constants</h2>
<p>A given "variable" is defined with either the <code>var</code> or
<code>con</code> keyword, for mutable and immutable assignment
respectively, alonside the assignment operator, <code>&lt;-</code>. An
uninitialized variable MUST have an explicit type, and cannot be
accessed until it is assigned. A variable that is initialized in its
declaration may have an explicit type, but the type may be inferred
here, when possible, if one is omitted. Normal type-coercion rules apply
in assignments, as described in the <em>Coercion and Casting</em>
section.</p>
<p>Non-ascii unicode characters are allowed in variable names as long as
the character doesn't cause a parsing issue. For example, whitespace
tokens are not allowed in variable names.</p>
<p>Some examples of assigning variables:</p>
<pre class="gp1"><code>var x: i32; // x is an uninitialized 32-bit signed integer
var y &lt;- x; // this won&#39;t work, because x has no value
x &lt;- 7;
var y &lt;- x; // this time it works, because x is now 7
con a: f64 &lt;- 99.8; // a is immutable
a &lt;- 44.12; // this doesn&#39;t work, because con variables cannot be reassigned</code></pre>
<p>The following lines are equivalent,</p>
<pre class="gp1"><code>con a &lt;- f64(7.2);
con a: f64 &lt;- 7.2;
con a &lt;- 7.2; // 7.2 is implicitly of type f64
con a &lt;- 7.2D; // With an explicit type suffix</code></pre>
<p>as are these.</p>
<pre class="gp1"><code>var c: f32 &lt;- 9;
var c &lt;- f32(9);
var c: f32 &lt;- f32(9);
var c &lt;- 9F;</code></pre>
<p>Variable assignments are expressions in GP1, which can enable some
very interesting code patterns. For example, it allows multiple
assignments on one line with the following syntax.
<code>con a &lt;- var b &lt;- "death and taxes"</code> assigns the
string <code>"death and taxes"</code> to both <code>a</code> and
<code>b</code>, leaving you with one constant and one variable
containing separate instances of identical data. This is equivalent to
writing <code>con a &lt;- "death and taxes"</code> and
<code>var b &lt;- "death and taxes"</code> each on their own line.
Assignment as an expression also eliminates much of the need to define
variables immediately before the control structure in which they're
used, which improves readability.</p>
<h2 id="intrinsic-types">Intrinsic Types</h2>
<h3 id="numeric-types">Numeric Types</h3>
<p><code>u8</code> <code>u16</code> <code>u32</code> <code>u64</code>
<code>u128</code> <code>u256</code> <code>usize</code>
<code>byte</code></p>
<p><code>i8</code> <code>i16</code> <code>i32</code> <code>i64</code>
<code>i128</code> <code>i256</code> <code>isize</code></p>
<p><code>f16</code> <code>f32</code> <code>f64</code> <code>f128</code>
<code>f256</code></p>
<p>GP1 has signed integer, unsigned integer, and floating point numeric
types. Numeric types take the form of a single-letter indicator followed
by the type's size in bits. The indicators are <strong>i</strong>
(signed integer), <strong>u</strong> (unsigned integer), and
<strong>f</strong> (floating point). <code>usize</code> and
<code>isize</code> are pointer-width types. For example, on a 64-bit
system, <code>usize</code> is a 64-bit unsigned integer. However, it
must be cast to <code>u64</code> when assigning to a <code>u64</code>
variable. The type <code>byte</code> is an alias for <code>u8</code>.
Numeric operators are as one expects from C, with the addition of
<code>**</code> as a power operator.</p>
<p>Numeric literals have an implicit type, or the type can be specified
by a case-insensitive suffix. For example:</p>
<pre class="gp1"><code>var i1 &lt;- 1234; // implicitly i32
var f1 &lt;- 1234.5; // implicitly f64
var i3 &lt;- 1234L; // i64
var u3 &lt;- 1234ui; // u32
var f2 &lt;- 1234.6F; // f32</code></pre>
<p>The complete set of suffixes is given.</p>
<table>
<thead>
<tr class="header">
<th>suffix</th>
<th>corresponding type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>s</td>
<td>i16</td>
</tr>
<tr class="even">
<td>i</td>
<td>i32</td>
</tr>
<tr class="odd">
<td>l</td>
<td>i64</td>
</tr>
<tr class="even">
<td>p</td>
<td>isize</td>
</tr>
<tr class="odd">
<td>b</td>
<td>byte</td>
</tr>
<tr class="even">
<td>us</td>
<td>u16</td>
</tr>
<tr class="odd">
<td>ui</td>
<td>u32</td>
</tr>
<tr class="even">
<td>ul</td>
<td>u64</td>
</tr>
<tr class="odd">
<td>up</td>
<td>usize</td>
</tr>
<tr class="even">
<td>f</td>
<td>f32</td>
</tr>
<tr class="odd">
<td>d</td>
<td>f64</td>
</tr>
<tr class="even">
<td>q</td>
<td>f128</td>
</tr>
</tbody>
</table>
<h3 id="booleans">Booleans</h3>
<p><code>bool</code> is the standard boolean type with support for all
the usual operations. The boolean literals are <code>true</code> and
<code>false</code>. Bool operators are as one expects from C, with the
exception that NOT is <code>!!</code> instead of <code>!</code>.</p>
<h3 id="bitwise-operators">Bitwise Operators</h3>
<p>Bitwise operators can be applied only to integers and booleans. They
are single counterparts of the doubled boolean operators, e.g. boolean
negation is <code>!!</code>, so bitwise negation is <code>!</code>.</p>
<h3 id="strings-and-characters">Strings and Characters</h3>
<p><code>char</code> is a unicode character of variable size. Char
literals are single-quoted, e.g. <code>'c'</code>. Any single valid char
value can be used as a literal in this fasion.</p>
<p><code>string</code> is a unicode string. String literals are
double-quoted, e.g. <code>"Hello, World."</code>.</p>
<h3 id="arrays">Arrays</h3>
<p>GP supports typical array operations.</p>
<pre class="gp1"><code>var tuples : (int, int)[]; // declare array of tuples
var strings : string[]; // declare array of strings
var array &lt;- i32[n]; // declare and allocate array of n elements
// n is any number that can be coerced to usize
con nums &lt;- {1, 2, 3}; // immutable array of i32
</code></pre>
<p>Use the <code>length</code> property to access the number of elements
in an allocated array. Attempting to access <code>length</code> of an
unallocated array is an exception.</p>
<pre class="gp1"><code>
var colors &lt;- {&quot;Red&quot;, &quot;White&quot;, &quot;Blue&quot;}; // allocate array
var count &lt;- colors.length; // count is usize(3)
</code></pre>
<p>Arrays can be indexed with any integer type (signed or unsigned).
Negative values wrap from the end (-1 is the last element). An exception
occurs if the value is too big, i.e.no modulo operation is
performed.</p>
<pre class="gp1"><code>var w &lt;- {1, 2, 3, 4, 5, 6, 7};
w[0] // first element, 1
w[-1] // last element, 7
var x &lt;- isize(-5);
w[x] // 5th to last element, 3
</code></pre>
<h3 id="tuples">Tuples</h3>
<p>Tuples group multiple values into a single value with anonymous,
ordered fields. <code>()</code> is an empty tuple.
<code>("hello", i32(17))</code> is a tuple of type
<code>(string i32)</code>. Tuple fields are named like indices,
i.e.<code>(u128(4), "2").1</code> would be <code>"2"</code>.</p>
<p>The unit type, represented as a 0-tuple, is written
<code>()</code>.</p>
<h3 id="regex">Regex</h3>
<p><code>regex</code> is a regular expression. GP1 regex format is
identical to that of .NET 5 and very similar to that of gawk.</p>
<h2 id="named-functions">Named Functions</h2>
<p>Some examples of defining named functions:</p>
<pre class="gp1"><code>fn sum(a: f32, b: f32): f32 { a + b } // takes parameters and returns an f32
fn twice_println(s: string) { // takes parameters and implicitly returns ()
println(&quot;${s}\n${s}&quot;);
}
fn join_println(a: string, b: string): () { // takes parameters and explicitly returns ()
println(&quot;${a} ${b}&quot;);
}
fn seven(): u32 { 7 } // takes no parameters and returns the u32 value of 7</code></pre>
<p>There are a number of syntaxes allowed for calling a given function.
This is because the caller is allowed to assign to zero or more of that
function's parameters by name. Parameters assigned by name are freely
ordered, while those assigned normally bind to the first parameter
ordered from left to right in the function definition that is
unassigned. With regard to the <code>join_println</code> function
defined above, this means that all of the following are valid and behave
identically.</p>
<pre class="gp1"><code>join_println(a &lt;- &quot;Hello,&quot;, b &lt;- &quot;World.&quot;);
join_println(b &lt;- &quot;World.&quot;, a &lt;- &quot;Hello,&quot;);
join_println(b &lt;- &quot;World.&quot;, &quot;Hello,&quot;);
join_println(&quot;Hello,&quot;, &quot;World.&quot;);</code></pre>
<p>Function names may be overloaded. For example,
<code>join_println</code> could be additionally defined as</p>
<pre class="gp1"><code>fn join_println(a: string, b: string, sep: string) {
println(&quot;${a}${sep}${b}&quot;);
}</code></pre>
<p>and then both <code>join_println("Hello,", "World.", " ")</code> and
<code>join_println("Hello,", "World.")</code> would be valid calls.</p>
<p>Functions may be defined and called within other functions. You may
be familar with this pattern from functional languages like F#, wherein
a wrapper function is often used to guard an inner recursive function
(GP1 permits both single and mutual recursion in functions). For
example:</p>
<pre class="gp1"><code>fn factorial(n: u256): u256 {
fn aux(n: u256, accumulator: u256): u256 {
match n &gt; 1 {
true =&gt; aux(n - 1, accumulator * n),
_ =&gt; accumulator,
}
}
aux(n, 1)
}</code></pre>
<p>Arguments are passed by value by default. For information on the
syntax used in this example, refer to <em>Control Flow</em>.</p>
<h2 id="anonymous-functions">Anonymous Functions</h2>
<h3 id="closures">Closures</h3>
<p>Closures behave as one would expect in GP1, exactly like they do in
most other programming languages that feature them. Closures look like
this:</p>
<pre class="gp1"><code>var x: u32 &lt;- 8;
var foo &lt;- { y, z =&gt; x * y * z}; // foo is a closure; its type is fn&lt;u32 | u32&gt;
assert(foo(3, 11) == (8 * 3 * 11)); // true
x &lt;- 5;
assert(foo(3) == (8 * 3 * 11)); // true
con bar &lt;- { =&gt; x * x }; // bar is a closure of type `fn&lt;u32&gt;`
assert(bar() == 25); // true because closure references already-defined x</code></pre>
<p>They are surrounded by curly braces. Within the curly braces goes an
optional, comma-separated parameter list, followed by a required
<code>=&gt;</code> symbol, followed by an optional expression. If no
expression is included, the closure implicitly returns
<code>()</code>.</p>
<p>The reason the match-expression uses the same <code>=&gt;</code>
symbol is because the <code>when</code> section of a match arm is an
implicit closure. The reason <code>=&gt;</code> in particular was chosen
for closures is twofold. One, arrows are conventional for expressing
anonymous functions, and two, the space between the lines of an equals
sign is enclosed by them.</p>
<h3 id="lambdas">Lambdas</h3>
<p>Lambdas are nearly identical to closures, but they don't close over
their environment, and they use the <code>-&gt;</code> symbol in place
of <code>=&gt;</code>. A few examples of lambdas:</p>
<pre class="gp1"><code>con x: u32 &lt;- 4; // this line is totally irrelevant
con square &lt;- { x -&gt; x * x }; // this in not valid, because the type of the function is not known
con square &lt;- { x: u32 -&gt; x * x }; // this if fine, because the type is specified in the lambda
con square: fn&lt;u32 | u32&gt; &lt;- { x -&gt; x * x }; // also fine, because the type is specified in the declaration</code></pre>
<h2 id="function-types">Function Types</h2>
<p>Functions are first-class citizens in GP1, so you can assign them to
variables, pass them as arguments, &amp;c.However, using the function
definition syntax is suboptimal when using function types. Instead,
there is a separate syntax for function types. Given the function
<code>fn sum(a: f64, b: f64): f64 { a + b }</code> the function type is
expressed <code>fn&lt;f64 f64 | f64&gt;</code>, meaning a function that
accepts two f64 values and returns an f64. Therefore,</p>
<pre class="gp1"><code>fn sum(a: f64, b: f64): f64 { a + b } </code></pre>
<pre class="gp1"><code>con sum: fn&lt;f64 f64 | f64&gt; &lt;- { a, b -&gt; a + b };</code></pre>
<pre class="gp1"><code>con sum &lt;- { a: f64, b: f64 -&gt; a + b };</code></pre>
<p>are all equivalent ways of binding a function of type
<code>fn&lt;f64 f64 | f64&gt;</code> to the constant <code>sum</code>.
Here's an example of how to express a function type for a function
argument.</p>
<pre class="gp1"><code>fn apply_op(a: i32, b: i32, op: fn&lt;i32 i32 | i32&gt;): i32 {
op(a, b)
}</code></pre>
<h3 id="function-type-inference">Function Type Inference</h3>
<p>The above example provides an explicit type for the argument
<code>op</code>. You could safely rewrite this as</p>
<pre class="gp1"><code>fn apply_op(a: i32, b: i32, op: fn): i32 {
op(a, b)
}</code></pre>
<p>because the compiler can safely infer the function type of
<code>op</code>. Type inference only works to figure out the function
signature, so <code>fn apply_op(a:i32, b:i32, op):i32 { . . . }</code>
is not allowed.</p>
<h2 id="coercion-and-casting">Coercion and Casting</h2>
<p>Refer to <em>Variables and Constants</em> for information on the
syntax used in this section.</p>
<p>Numeric types are automatically coerced into other numeric types as
long as that coercion is not lossy. For example,</p>
<pre class="gp1"><code>var x: i32 &lt;- 10;
var y: i64 &lt;- x;</code></pre>
<p>is perfectly legal (the 32-bit value fits nicely in the 64-bit
variable). However, automatic coercion doesn't work if it would be
lossy, so</p>
<pre class="gp1"><code>var x: i64 &lt;- 10;
var y: i32 &lt;- x;</code></pre>
<p>doesn't work. This holds for numeric literals as well.
Unsurprisingly, <code>var x: i32 &lt;- 3.14</code> wouldn't compile. The
floating point value can't be automatically coerced to an integer type.
So what does work? Casting via the target type's pseudo-constructor
works.</p>
<pre class="gp1"><code>con x: f64 &lt;- 1234.5; // okay because the literal can represent any floating point type
con y: f64 &lt;- f16(1234.5); // also okay, because any f16 can be losslessly coerced to an f64
con z: i32 &lt;- i32(x); // also okay; uses the i32 pseudo-constructor to &#39;cast&#39; x to a 32-bit integer
assert(z == 1234)
con a: f64 &lt;- 4 * 10 ** 38; // this value is greater than the greatest f32
con b: f32 &lt;- f32(a); // the value of b is the maximum value of f32</code></pre>
<p>This approach is valid for all intrinsic types. For example,
<code>var flag: bool &lt;- bool(0)</code> sets <code>flag</code> to
<code>false</code> and <code>var txt: string &lt;- string(83.2)</code>
sets <code>txt</code> to the string value <code>"83.2"</code>. Such
behavior can be implemented by a programmer on their own types via a
system we'll discuss in the <em>Interfaces</em> section.</p>
<h2 id="program-structure">Program Structure</h2>
<p>Every GP1 program has an entry-point function. Within that function,
statements are executed from top to bottom and left to right. The
entry-point function can be declared with the <code>entry</code> keyword
in place of <code>fn</code> and returns an integer, which will be
provided to the host operating system as an exit code. Naturally, this
means that the handling of that code is platform-dependent once it
passes the program boundry, so it's important to keep in mind that a
system may implicitly downcast or otherwise modify it before it is made
available to the user. If no exit code is specified, or if the return
type of the function is not an integer, GP1 assumes an exit code of
<code>usize(0)</code> and returns that to the operating system.</p>
<p>The following program prints Hello, World. and exits with an error
code.</p>
<pre class="gp1"><code>entry main(): usize {
hello_world();
1
}
fn hello_world() {
println(&quot;Hello, World.&quot;);
}</code></pre>
<p>The entry function may have any name; it's the <code>entry</code>
keyword that makes it the entry point. The entry function may also be
implicit. If one is not defined explicitly, the entire file is treated
as being inside an entry function. Therefore,</p>
<pre class="gp1"><code>println(&quot;Hello, World.&quot;);</code></pre>
<p>is a valid and complete program identical to</p>
<pre class="gp1"><code>entry main(): usize {
println(&quot;Hello, World.&quot;);
}</code></pre>
<p>This behavior can lend GP1 a very flexible feeling akin to many
scripting languages.</p>
<p>In a program where there is an entry-point specified, only
expressions made within that function will be evaluated. This means that
the following program does NOT print anything to the console.</p>
<pre class="gp1"><code>entry main(): usize {
con x: usize &lt;- 7;
}
println(&quot;This text will not be printed.&quot;);</code></pre>
<p>In fact, this program is invalid. Whenever there is an explicit entry
point, no statements may be made in the global scope.</p>
<h2 id="control-flow">Control Flow</h2>
<h3 id="conditionals">Conditionals</h3>
<p>At this time, GP1 has only one non-looping conditional control
structure, in two variants: <code>match</code> and
<code>match all</code>. The syntax is as follows, where
<code>*expr*</code> are expressions and <code>pattern*</code> are
pattern matching options (refer to <em>Pattern Matching</em> for more
info).</p>
<pre class="gp1"><code>match expr {
pattern1 =&gt; arm_expr1,
pattern2 =&gt; arm_expr2,
_ =&gt; arm_expr3,
}</code></pre>
<p>The <code>match</code> expression executes the first arm that matches
the pattern passed in <code>expr</code>. The <code>match all</code>
expression executes all arms that match the pattern. Both flavors return
their last executed expression.</p>
<p>The <code>when</code> keyword may be used in a given match arm to
further restrict the conditions of execution, e.g.</p>
<pre class="gp1"><code>con fs &lt;- 43;
con is_even &lt;- match fs {
n when n % 2 == 0 =&gt; &quot; is &quot;
_ =&gt; &quot; is not &quot;
};
print(fs + is_even + &quot;even.&quot;)</code></pre>
<h3 id="loops">Loops</h3>
<p>Several looping structures are supported in GP1</p>
<ul>
<li><code>loop</code></li>
<li><code>for</code></li>
<li><code>while</code></li>
<li><code>do/while</code></li>
</ul>
<p>along with <code>continue</code> and <code>break</code> to help
control program flow. All of these are statements.</p>
<pre class="gp1"><code>loop { . . . } // an unconditional loop -- runs forever or until broken</code></pre>
<pre class="gp1"><code>for i in some_iterable { . . . } // loop over anything that is iterable</code></pre>
<pre class="gp1"><code>while some_bool { . . . } // classic conditional loop that executes until the predicate is false</code></pre>
<pre class="gp1"><code>do { . . .
} while some_bool // traditional do/while loop that ensures body executes at least once</code></pre>
<h2 id="pattern-matching">Pattern Matching</h2>
<p>Pattern matching behaves essentially as it does in SML, with support
for various sorts of destructuring. It works in normal assignment and in
<code>match</code> arms. It will eventually work in function parameter
assignment, but perhaps not at first.</p>
<p>For now, some examples.</p>
<pre class="gp1"><code>a &lt;- (&quot;hello&quot;, &quot;world&quot;); // a is a tuple of strings
(b, c) &lt;- a;
assert(b == &quot;hello&quot; &amp;&amp; c == &quot;world&quot;)
fn u32_list_to_string(l: List&lt;u32&gt;): string { // this is assuming that square brackets are used for linked lists
con elements &lt;- match l {
[] =&gt; &quot;&quot;,
[e] =&gt; string(e),
h::t =&gt; string(h) + &quot;, &quot; + u32_list_to_string(t), // the bit before the arrow in each arm is a pattern
} // h::t matches the head and tail of the list to h and t, respectively
&quot;[&quot; + elements + &quot;]&quot; // [s] matches any single-element list
} // [] matches any empty list</code></pre>
<h2 id="interfaces">Interfaces</h2>
<p>Interfaces are in Version 2 on the roadmap.</p>
<h2 id="user-defined-types">User-Defined Types</h2>
<h3 id="enums">Enums</h3>
<p>Enums are pretty powerful in GP1. They can be the typical enumerated
type you'd expect, like</p>
<pre class="gp1"><code>enum Coin { penny, nickle, dime, quarter } // &#39;vanilla&#39; enum
var a &lt;- Coin.nickle
assert a == Coin.nickle
</code></pre>
<p>Or an enum can have an implicit field named <code>value</code></p>
<pre class="gp1"><code>enum Coin: u16 { penny(1), nickle(5), dime(10), quarter(25) }
var a &lt;- Coin.nickle;
assert(a == Coin.nickle);
assert(a.value == 5);</code></pre>
<p>Or an enum can be complex with a user-defined set of fields, like</p>
<pre class="gp1"><code>enum CarModel(make: string, mass: f32, wheelbase: f32) { // enum with multiple fields
gt ( &quot;ford&quot;, 1581, 2.71018 ),
c8_corvette ( &quot;chevy&quot;, 1527, 2.72288 )
}</code></pre>
<p>A field can also have a function type. For example</p>
<pre class="gp1"><code>enum CarModel(make: string, mass: f32, wheelbase: f32, gasUsage: fn&lt;f32 | f32&gt;) {
gt ( &quot;ford&quot;, 1581, 2.71018, { miles_traveled -&gt; miles_traveled / 14 } ),
c8_corvette ( &quot;chevy&quot;, 1527, 2.72288, { miles_traveled -&gt; miles_traveled / 19 } )
}
var my_car &lt;- CarModel.c8_corvette;
var gas_used &lt;- my_car.gasUsage(200); // estimate how much gas I&#39;d use on a 200 mile trip</code></pre>
<p>Equivalence of enums is not influenced by case values, e.g.</p>
<pre class="gp1"><code>enum OneOrAnother: u16 { one(0), another(0) }
con a &lt;- OneOrAnother.one;
con b &lt;- OneOrAnother.another;
assert(a != b);
assert(a.value == b.value);</code></pre>
<p>It's important to remember that enums are 100% always totally in
every concieveable fashion immutable. To make this easier to enforce,
only value types are allowed for enum fields.</p>
<h3 id="records">Records</h3>
<p>Records are record types, defined with the <code>record</code>
keyword. Fields are defined in the <code>record</code> block and
behavior is defined in the optional <code>impl</code> block.</p>
<p>For example,</p>
<pre class="gp1"><code>record Something {
label: i32 // field label followed by some type
} impl { . . . } // associated functions. This is different than having functions in the fields section because impl functions are not assignable.</code></pre>
<p>If the record implements some interface, <code>SomeInterface</code>,
the <code>impl</code> would be replaced with
<code>impl SomeInterface</code>, and the functions of
<code>SomeInterface</code> would be defined alongside any other
functions of the <code>Something</code> record.</p>
<h3 id="unions">Unions</h3>
<p>Unions are the classic discriminated sum type.</p>
<pre class="gp1"><code>union BinaryTree {
Empty,
Leaf: i32,
Node: (BinaryTree BinaryTree),
}</code></pre>
<h3 id="type-aliases">Type Aliases</h3>
<p>Refer to <em>Generics</em> for info on the syntax used in this
section.</p>
<p>Type aliasing is provided with the <code>type</code> keyword,
e.g.</p>
<pre class="gp1"><code>type TokenStream Sequence&lt;Token&gt;
type Ast Tree&lt;AbstractNode&gt;
fn parse(ts: TokenStream): Ast { . . . }</code></pre>
<p>Notice how much cleaner the function definition looks with the
aliased types. This keyword is useful mainly for readability and domain
modeling.</p>
<h2 id="generics">Generics</h2>
<p>Generics are in Version 2 on the official GP1 roadmap. They roughly
use C++ template syntax or Rust generic syntax.</p>
<h2 id="references-and-reference-types">References and Reference
Types</h2>
<p>GP1 has three operators involved in handling references,
<code>#</code>, <code>&amp;</code>, and <code>@</code>. These are
immutable reference, mutable reference, and dereference, respectively.
Some examples of referencing/dereferencing values:</p>
<pre class="gp1"><code>var a &lt;- &quot;core dumped&quot;;
var b &lt;- &amp;a; // b is a mutable reference to a
assert(a == @b);
assert(a != b);
@b &lt;- &quot;missing ; at line 69, column 420&quot;;
assert(a == &quot;missing ; at line 69, column 420&quot;);
b &lt;- &amp;&quot;missing ; at line 420, column 69&quot;;
assert(a != &quot;missing ; at line 420, column 69&quot;);
var c &lt;- #b; // c is an immutable reference to b
assert(@c == b);
assert(@@c == a);
@c &lt;- &amp;&quot;kablooey&quot;; // this does not work. `c` is an immutable reference and cannot be used to assign its referent.</code></pre>
<p>Naturally, only <code>var</code> values can be mutated through
references.</p>
<p>The reference operators may be prepended to any type, T, to describe
the type of a reference to a value of type T, e.g.</p>
<pre class="gp1"><code>fn set_through(ref: &amp;string) { // this function takes a mutable reference to a string and returns `()`
@ref &lt;- &quot;goodbye&quot;;
}
var a &lt;- &quot;hello&quot;;
set_through(&amp;a);
assert(a == &quot;goodbye&quot;);</code></pre>

1
site/acl.cool/assets Symbolic link
View file

@ -0,0 +1 @@
../assets

70
site/acl.cool/cats.ml Normal file
View file

@ -0,0 +1,70 @@
module type Functor = sig
type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
end
module type Applicative = sig
type 'a t
val pure : 'a -> 'a t
val apply : ('a -> 'b) t -> 'a t -> 'b t
end
module type Monad = sig
type 'a t
val return : 'a -> 'a t
val bind : ('a -> 'b t) -> 'a t -> 'b t
end
module ApplicativeOfMonad (M : Monad) : Applicative with type 'a t = 'a M.t = struct
type 'a t = 'a M.t
let pure = M.return
let apply f x = M.(bind (fun y -> bind (fun g -> return (g y)) f) x)
end
module FunctorOfApplicative (A : Applicative) : Functor with type 'a t = 'a A.t = struct
type 'a t = 'a A.t
let map f x = A.(apply (pure f) x)
end
module FunctorOfMonad (M : Monad) : Functor with type 'a t = 'a M.t = struct
include FunctorOfApplicative(ApplicativeOfMonad(M))
end
module MonadDerive (M : Monad) = struct
include M
include ApplicativeOfMonad(M)
include FunctorOfMonad(M)
let (>>=) x f = bind f x
let (<$>) x f = map x f
let (<*>) x f = apply x f
end
module ListMonad = struct
type 'a t = 'a list
let return x = [x]
let rec bind (f : 'a -> 'b list) : 'a list -> 'b list = function
| [] -> []
| x :: xs -> f x @ bind f xs
end
module Dlm = MonadDerive(ListMonad)
let pair x y = x, y
let cart_prod xs ys = Dlm.(pair <$> xs <*> ys)
let () = cart_prod [1;2;3;4] ["7"; "hello there"; "forthwith!"]
|> List.iter (fun (x, y) -> print_endline @@ "(" ^ string_of_int x ^ ", " ^ y ^ ")")
(* ============================================================================================= *)
module StateMonad (S : sig type t end) = struct
type 'a t = S.t -> S.t * 'a
let return x s = (s, x)
let bind f x s = let s', a = x s in f a s'
end
module IntStateMonad = StateMonad(struct type t = int end)

70
site/acl.cool/cats.ml.txt Normal file
View file

@ -0,0 +1,70 @@
module type Functor = sig
type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
end
module type Applicative = sig
type 'a t
val pure : 'a -> 'a t
val apply : ('a -> 'b) t -> 'a t -> 'b t
end
module type Monad = sig
type 'a t
val return : 'a -> 'a t
val bind : ('a -> 'b t) -> 'a t -> 'b t
end
module ApplicativeOfMonad (M : Monad) : Applicative with type 'a t = 'a M.t = struct
type 'a t = 'a M.t
let pure = M.return
let apply f x = M.(bind (fun y -> bind (fun g -> return (g y)) f) x)
end
module FunctorOfApplicative (A : Applicative) : Functor with type 'a t = 'a A.t = struct
type 'a t = 'a A.t
let map f x = A.(apply (pure f) x)
end
module FunctorOfMonad (M : Monad) : Functor with type 'a t = 'a M.t = struct
include FunctorOfApplicative(ApplicativeOfMonad(M))
end
module MonadDerive (M : Monad) = struct
include M
include ApplicativeOfMonad(M)
include FunctorOfMonad(M)
let (>>=) x f = bind f x
let (<$>) x f = map x f
let (<*>) x f = apply x f
end
module ListMonad = struct
type 'a t = 'a list
let return x = [x]
let rec bind (f : 'a -> 'b list) : 'a list -> 'b list = function
| [] -> []
| x :: xs -> f x @ bind f xs
end
module Dlm = MonadDerive(ListMonad)
let pair x y = x, y
let cart_prod xs ys = Dlm.(pair <$> xs <*> ys)
let () = cart_prod [1;2;3;4] ["7"; "hello there"; "forthwith!"]
|> List.iter (fun (x, y) -> print_endline @@ "(" ^ string_of_int x ^ ", " ^ y ^ ")")
(* ============================================================================================= *)
module StateMonad (S : sig type t end) = struct
type 'a t = S.t -> S.t * 'a
let return x s = (s, x)
let bind f x s = let s', a = x s in f a s'
end
module IntStateMonad = StateMonad(struct type t = int end)

1
site/acl.cool/css Symbolic link
View file

@ -0,0 +1 @@
../css

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 12.1.0 (20240811.2233)
-->
<!-- Pages: 1 -->
<svg width="844pt" height="426pt"
viewBox="0.00 0.00 843.85 425.92" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 421.92)">
<polygon fill="white" stroke="none" points="-4,4 -4,-421.92 839.85,-421.92 839.85,4 -4,4"/>
<!-- cp -->
<g id="node1" class="node">
<title>cp</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="102.53" cy="-375" rx="96.17" ry="19.45"/>
<text text-anchor="start" x="42.53" y="-372.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Consider Phlebas</text>
</g>
<!-- ltw -->
<g id="node7" class="node">
<title>ltw</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="102.53" cy="-209" rx="102.53" ry="19.45"/>
<text text-anchor="start" x="38.03" y="-206.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Look to Windward</text>
</g>
<!-- cp&#45;&gt;ltw -->
<g id="edge1" class="edge">
<title>cp&#45;&gt;ltw</title>
<path fill="none" stroke="black" d="M102.53,-355.19C102.53,-327.09 102.53,-273.87 102.53,-240.26"/>
<polygon fill="black" stroke="black" points="106.03,-240.36 102.53,-230.36 99.03,-240.36 106.03,-240.36"/>
</g>
<!-- pog -->
<g id="node2" class="node">
<title>pog</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="392.53" cy="-375" rx="112.08" ry="19.45"/>
<text text-anchor="start" x="321.28" y="-372.45" font-family="Open Sans" font-weight="bold" font-size="14.00">The Player of Games</text>
</g>
<!-- uow -->
<g id="node3" class="node">
<title>uow</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="312.53" cy="-209" rx="89.8" ry="19.45"/>
<text text-anchor="start" x="257.03" y="-206.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Use of Weapons</text>
</g>
<!-- sota -->
<g id="node4" class="node">
<title>sota</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="311.53" cy="-43" rx="107.3" ry="19.45"/>
<text text-anchor="start" x="243.66" y="-40.45" font-family="Open Sans" font-weight="bold" font-size="14.00">The State of the Art</text>
</g>
<!-- uow&#45;&gt;sota -->
<g id="edge2" class="edge">
<title>uow&#45;&gt;sota</title>
<path fill="none" stroke="black" d="M312.42,-189.19C312.24,-161.09 311.92,-107.87 311.71,-74.26"/>
<polygon fill="black" stroke="black" points="315.22,-74.34 311.65,-64.36 308.22,-74.38 315.22,-74.34"/>
</g>
<!-- ivs -->
<g id="node6" class="node">
<title>ivs</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="499.53" cy="-43" rx="62.23" ry="19.45"/>
<text text-anchor="start" x="463.53" y="-40.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Inversions</text>
</g>
<!-- uow&#45;&gt;ivs -->
<g id="edge3" class="edge">
<title>uow&#45;&gt;ivs</title>
<path fill="none" stroke="black" d="M333.26,-189.82C366.71,-160.48 432.69,-102.62 470.71,-69.28"/>
<polygon fill="black" stroke="black" points="472.93,-71.98 478.14,-62.76 468.32,-66.72 472.93,-71.98"/>
</g>
<!-- sd -->
<g id="node9" class="node">
<title>sd</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="104.53" cy="-43" rx="80.26" ry="19.45"/>
<text text-anchor="start" x="55.78" y="-40.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Surface Detail</text>
</g>
<!-- uow&#45;&gt;sd -->
<g id="edge6" class="edge">
<title>uow&#45;&gt;sd</title>
<path fill="none" stroke="black" d="M289.48,-189.82C252.21,-160.44 178.64,-102.44 136.39,-69.12"/>
<polygon fill="black" stroke="black" points="138.58,-66.39 128.56,-62.95 134.25,-71.89 138.58,-66.39"/>
</g>
<!-- ex -->
<g id="node5" class="node">
<title>ex</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="613.53" cy="-375" rx="58.51" ry="19.45"/>
<text text-anchor="start" x="580.16" y="-372.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Excession</text>
</g>
<!-- mat -->
<g id="node8" class="node">
<title>mat</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="539.53" cy="-209" rx="45.25" ry="19.45"/>
<text text-anchor="start" x="515.53" y="-206.45" font-family="Open Sans" font-weight="bold" font-size="14.00">Matter</text>
</g>
<!-- ex&#45;&gt;mat -->
<g id="edge5" class="edge">
<title>ex&#45;&gt;mat</title>
<path fill="none" stroke="black" d="M605.19,-355.51C592.29,-326.93 567.44,-271.85 552.28,-238.27"/>
<polygon fill="black" stroke="black" points="555.66,-237.23 548.35,-229.56 549.28,-240.11 555.66,-237.23"/>
</g>
<!-- hs -->
<g id="node10" class="node">
<title>hs</title>
<ellipse fill="#cceedd" stroke="#aaaaaa" cx="719.53" cy="-209" rx="116.32" ry="19.45"/>
<text text-anchor="start" x="645.28" y="-206.45" font-family="Open Sans" font-weight="bold" font-size="14.00">The Hydrogen Sonata</text>
</g>
<!-- ex&#45;&gt;hs -->
<g id="edge4" class="edge">
<title>ex&#45;&gt;hs</title>
<path fill="none" stroke="black" d="M625.48,-355.51C644.01,-326.84 679.79,-271.49 701.48,-237.93"/>
<polygon fill="black" stroke="black" points="704.15,-240.25 706.64,-229.95 698.27,-236.45 704.15,-240.25"/>
</g>
<!-- ltw&#45;&gt;sd -->
<g id="edge7" class="edge">
<title>ltw&#45;&gt;sd</title>
<path fill="none" stroke="black" d="M102.76,-189.19C103.1,-161.09 103.75,-107.87 104.16,-74.26"/>
<polygon fill="black" stroke="black" points="107.66,-74.4 104.28,-64.36 100.66,-74.32 107.66,-74.4"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -0,0 +1,21 @@
digraph {
node [style=filled, fontname="Open Sans", fillcolor="#cceeddff", color="#aaaaaaff"];
ratio=0.5;
cp [label=<<B>Consider Phlebas</B>>];
pog [label=<<B>The Player of Games</B>>];
uow [label=<<B>Use of Weapons</B>>];
sota [label=<<B>The State of the Art</B>>];
ex [label=<<B>Excession</B>>];
ivs [label=<<B>Inversions</B>>];
ltw [label=<<B>Look to Windward</B>>];
mat [label=<<B>Matter</B>>];
sd [label=<<B>Surface Detail</B>>];
hs [label=<<B>The Hydrogen Sonata</B>>];
cp -> ltw; // It's about the Idiran War, dummy.
uow -> sota; // It's largely about Sma.
uow -> ivs; // This book gives the best idea about what SC is, and you should know that before reading Inversions.
ex -> hs; // Hydrogen Sonata is dual to Excession in many ways. Not a hard rule, but HS is better if you know Excession.
ex -> mat; // Sleeper Service mentioned as "The granddaddy, the exemplary hero figure, the very God...".
uow -> sd; // Zakalwe/chair killer is in this one, and you should know who that is.
ltw -> sd; // LTW is more impactful (with Chel heaven being specially real) without the knowledge of SD.
}

3
site/acl.cool/index.html Normal file
View file

@ -0,0 +1,3 @@
<h1>acl.cool</h1>
<p>Welcome to acl.cool.</p> <a href="recipes/">recipes</a>

BIN
site/acl.cool/msvcr110.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,3 @@
+ [Coronation Chicken](CoronationChicken.pdf)
+ [Easy Medium Salsa](EasySalsa.pdf)
+ [Amaretti Cookies](AmarettiCookies.pdf)

BIN
site/acl.cool/resume.pdf Executable file

Binary file not shown.

112
site/acl.cool/resume.typ Executable file
View file

@ -0,0 +1,112 @@
#let fontsize = 10.2pt
#let typeface_text = "Fira Sans"
#let typeface_math = "STIX Two Math"
#set text(font: typeface_text, size: fontsize)
#show math.equation: set text(font: typeface_math, size: fontsize)
#let inlineFrac(a, b) = [$#super([#a]) #h(-1pt) slash #h(-1pt) #sub([#b])$]
#set smartquote(enabled: false)
#show heading: q => {
if q.depth != 1 {
v(fontsize / 5)
}
text(q, weight: "regular")
if q.depth == 2 {
v(-0.7em)
line(length: 100%, stroke: (thickness: 0.7pt))
v(0.5em)
}
}
#let head = {
align(center)[
= Alexander Lucas
#set text(font: "Fira Code")
#text([alexander.clay.lucas\@gmail.com], size: fontsize * 0.9)
#linebreak()
#text([(+1) 347-644-9265], size: fontsize * 0.8)
]
}
#set page(margin: (x: 0.9in, y: 0.35in))
#head
== Summary
I am a computer science enthusiast with an inclination for harnessing computer science
theory to tackle practical challenges as cleanly as possible. I believe strongly in the
importance of codebase health and quality, maintaining those values over time as programs and projects evolve.
== Skills
#let skills = [
*Languages*: Javascript/Typescript, Java, Python, Rust, Haskell, OCaml, F\#, Ruby, C\#, C, C++, Lean 4, HTML/CSS, LaTeX, Typst
#linebreak()
*Platforms*: Ten years using GNU/Linux including Debian and Redhat, QEMU, Google Cloud
#linebreak()
*Technologies*: Buildroot, WebGL, Numpy/Pytorch/Sklearn, Matplotlib, Git, Gitlab/Github, PostgreSQL, Node, Slurm
#linebreak()
*Soft Skills*: Technical Writing, Software Documentation, Presentation
]
#skills
#let interline() = {
box(width: 1fr, inset: fontsize / 4, line(length: 100%, stroke: (thickness: fontsize / 10, dash: "loosely-dotted")))
}
== Experience
#let experience = [
*Embedded Software Engineer, Jr.* #interline() #text(weight: "semibold")[Trusted Microelectronics, KBR, 01/2025-05/2025 (End of Funds)]
- Continuing to work with the same great team, tools and software as during my internship.
- Developing QEMU virtual hardware devices for building/testing platform-specific applications.
*Linux Driver Development Intern* #interline() #text(weight: "semibold")[Trusted Microelectronics, KBR, 05/2024-08/2024]
- Learned Linux kernel subsystems and developed device drivers for custom "system on a chip" hardware, including GPIO/pin controllers and an AES encryption accelerator module.
- Worked with team members to develop testing and assurance methodologies including coverage profiling and input fuzzing for Linux drivers while porting Linux to our boards.
- Automated common tasks, writing scripts to handle OS installations and code restructuring.
- Presented project status and details to large, cross-functional and interdisciplinary groups.
*Teaching Assistant* #interline() #text(weight: "semibold")[James Madison University, 08/2022-12/2023]
- Took questions and led review sessions in proofs, programming, tooling, debugging code.
- Maintained a calm and encouraging environment while helping students with difficult problem sets against a deadline.
]
#experience
== Education
#let degrees = [
*B.S. Computer Science* (3.8 GPA) #interline() #text(weight: "semibold")[James Madison University, 12/2023]
]
#degrees
#let courses = [
- Programming Languages, Compiler Construction
- Independent Study in Constructive Logic, Symbolic Logic
- Applied Algorithms, Data Structures
- Parallel and Distributed Systems, 3D Graphics
]
#courses
*Study Abroad, London, UK* #interline() #text(weight: "semibold")[JMU at Florida State Study Center, Summer 2023]
#let cw = [
- Rigidity Theory
- Independent Study in Computational Geometry
]
#cw
*Academic Awards*
#let awards = [
- "President's List" #interline() #text(weight: "semibold")[JMU, 2023]
- "Alonzo Church Award for Theory" #interline() #text(weight: "semibold")[JMU CS Department, 2024]
]
#awards
== Personal Projects
#let projects = [
*Aasam* (on #underline([#link("https://hackage.haskell.org/package/aasam")[Hackage]])) is a Haskell implementation of the CFG-generation algorithm $#math.cal([M])$ from Annika Aasa's paper "Precedences in specifications and implementations of programming languages".
#linebreak()
*Randall* (on #underline([#link("https://gitlab.com/mobotsar/randall")[Gitlab]])) is a Discord bot for executing dice-notation, making it easy to play TTRPGs remotely. It uses a recursive descent parser and tree-walk interpreter on the backend and the .NET Discord library up front.
]
#projects

View file

@ -0,0 +1 @@
b481aac1-ef8d-48d0-8d6b-b109c992addd

View file

@ -0,0 +1 @@
{"weight":350,"italic":false,"alternates":{"cv01":false,"cv02":false,"cv03":false,"cv04":false,"cv05":false,"cv06":true,"cv07":false,"cv08":true,"cv09":false,"cv10":false,"cv11":false},"features":{"ss01":false,"ss02":false,"ss03":false,"ss04":true,"ss05":true},"letterSpacing":0,"lineHeight":1,"fontName":"UnfancyDevN"}

View file

@ -0,0 +1,11 @@
A short guide for how to install and enable your shiny new version of Commit Mono.
This is taken from section 08 Install from https://commitmono.com/
#1 (Download the fonts)
#2 Unzip the fonts. You'll see 4 font files. These 4 fonts make up a 'Style Group':
* CommitMono-Regular: Base version with settings and weight of your choice.
* CommitMono-Italic: An italic version, same weight as regular.
* CommitMono-Bold: A bold version, weight 700.
* CommitMono-BoldItalic: A bold version, weight 700, that is also italic.
#3 Install all 4 fonts on your system:
* Windows: Right click the font in the folder and click "Instal

View file

@ -0,0 +1,37 @@
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the compon

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,43 @@
# Installing Webfonts
Follow these simple Steps.
## 1.
Put `rowan/` Folder into a Folder called `fonts/`.
## 2.
Put `rowan.css` into your `css/` Folder.
## 3. (Optional)
You may adapt the `url('path')` in `rowan.css` depends on your Website Filesystem.
## 4.
Import `rowan.css` at the top of you main Stylesheet.
```
@import url('rowan.css');
```
## 5.
You are now ready to use the following Rules in your CSS to specify each Font Style:
```
font-family: Rowan-Light;
font-family: Rowan-LightItalic;
font-family: Rowan-Regular;
font-family: Rowan-Italic;
font-family: Rowan-Medium;
font-family: Rowan-MediumItalic;
font-family: Rowan-Semibold;
font-family: Rowan-SemiboldItalic;
font-family: Rowan-Bold;
font-family: Rowan-BoldItalic;
font-family: Rowan-Variable;
font-family: Rowan-VariableItalic;
```
## 6. (Optional)
Use `font-variation-settings` rule to controll axes of variable fonts:
wght 700.0
Available axes:
'wght' (range from 300.0 to 700.0

View file

@ -0,0 +1,148 @@
/**
* @license
*
* Font Family: Rowan
* Designed by: Inga Plönnigs
* URL: https://www.fontshare.com/fonts/rowan
* © 2025 Indian Type Foundry
*
* Rowan Light
* Rowan LightItalic
* Rowan Regular
* Rowan Italic
* Rowan Medium
* Rowan MediumItalic
* Rowan Semibold
* Rowan SemiboldItalic
* Rowan Bold
* Rowan BoldItalic
* Rowan Variable (Variable font)
* Rowan VariableItalic (Variable font)
*
*/
@font-face {
font-family: 'Rowan-Light';
src: url('../fonts/Rowan-Light.woff2') format('woff2'),
url('../fonts/Rowan-Light.woff') format('woff'),
url('../fonts/Rowan-Light.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Rowan-LightItalic';
src: url('../fonts/Rowan-LightItalic.woff2') format('woff2'),
url('../fonts/Rowan-LightItalic.woff') format('woff'),
url('../fonts/Rowan-LightItalic.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Rowan-Regular';
src: url('../fonts/Rowan-Regular.woff2') format('woff2'),
url('../fonts/Rowan-Regular.woff') format('woff'),
url('../fonts/Rowan-Regular.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Rowan-Italic';
src: url('../fonts/Rowan-Italic.woff2') format('woff2'),
url('../fonts/Rowan-Italic.woff') format('woff'),
url('../fonts/Rowan-Italic.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Rowan-Medium';
src: url('../fonts/Rowan-Medium.woff2') format('woff2'),
url('../fonts/Rowan-Medium.woff') format('woff'),
url('../fonts/Rowan-Medium.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Rowan-MediumItalic';
src: url('../fonts/Rowan-MediumItalic.woff2') format('woff2'),
url('../fonts/Rowan-MediumItalic.woff') format('woff'),
url('../fonts/Rowan-MediumItalic.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Rowan-Semibold';
src: url('../fonts/Rowan-Semibold.woff2') format('woff2'),
url('../fonts/Rowan-Semibold.woff') format('woff'),
url('../fonts/Rowan-Semibold.ttf') format('truetype');
font-weight: 600;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Rowan-SemiboldItalic';
src: url('../fonts/Rowan-SemiboldItalic.woff2') format('woff2'),
url('../fonts/Rowan-SemiboldItalic.woff') format('woff'),
url('../fonts/Rowan-SemiboldItalic.ttf') format('truetype');
font-weight: 600;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Rowan-Bold';
src: url('../fonts/Rowan-Bold.woff2') format('woff2'),
url('../fonts/Rowan-Bold.woff') format('woff'),
url('../fonts/Rowan-Bold.ttf') format('truetype');
font-weight: 700;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Rowan-BoldItalic';
src: url('../fonts/Rowan-BoldItalic.woff2') format('woff2'),
url('../fonts/Rowan-BoldItalic.woff') format('woff'),
url('../fonts/Rowan-BoldItalic.ttf') format('truetype');
font-weight: 700;
font-display: swap;
font-style: italic;
}
/**
* This is a variable font
* You can control variable axes as shown below:
* font-variation-settings: wght 700.0;
*
* available axes:
'wght' (range from 300.0 to 700.0
*/
@font-face {
font-family: 'Rowan-Variable';
src: url('../fonts/Rowan-Variable.woff2') format('woff2'),
url('../fonts/Rowan-Variable.woff') format('woff'),
url('../fonts/Rowan-Variable.ttf') format('truetype');
font-weight: 300 700;
font-display: swap;
font-style: normal;
}
/**
* This is a variable font
* You can control variable axes as shown below:
* font-variation-settings: wght 700.0;
*
* available axes:
'wght' (range from 300.0 to 700.0
*/
@font-face {
font-family: 'Rowan-VariableItalic';
src: url('../fonts/Rowan-VariableItalic.woff2') format('woff2'),
url('../fonts/Rowan-VariableItalic.woff') format('woff'),
url('../fonts/Rowan-VariableItalic.ttf') format('truetype');
font-weight: 300 700;
font-display: swap;
font-style: italic;
}

View file

@ -0,0 +1,57 @@
Fontshare EULA
---—---------------------------------—------------------------------
Free Font - End User License Agreement (FF EULA)
---—---------------------------------—------------------------------
Notice to User
Indian Type Foundry designs, produces and distributes font software as digital fonts to end users worldwide. In addition to commercial fonts that are available for a fee, ITF also offers several fonts which can be used free of charge. The free fonts are distributed through a dedicated platform called www.fontshare.com (“Fontshare”) to end users worldwide. These free fonts are subject to this legally binding EULA between the Indian Type Foundry (“Indian Type Foundry” or “Licensor”) and you (“Licensee”). 
You acknowledge that the Font Software and designs embodied therein are protected by the copyright, other intellectual property rights and industrial property rights and by international treaties. They are and remain at all times the intellectual property of the Indian Type Foundry.
In addition to direct download, Fontshare also offers these free fonts via Fonthsare API using a code. In this case, the Font Software is delivered directly from the servers used by Indian Type Foundry to the Licensee's website, without the Licensee having to download the Font Software.
By downloading, accessing the API, installing, storing, copying or using one of any Font Software, you agree to the following terms. 
Definitions
“Font Software” refers to the set of computer files or programs released under this license that instructs your computer to display and/or print each letters, characters, typographic designs, ornament and so forth. Font Software includes all bitmap and vector representations of fonts and typographic representations and embellishments created by or derived from the Font Software. 
“Original Version” refers to the Font Software as distributed by the Indian Type Foundry as the copyright holder. 
“Derivative Work” refers to the pictorial representation of the font created by the Font Software, including typographic characters such as letters, numerals, ornaments, symbols, or punctuation and special characters.
01. Grant of License
You are hereby granted a non-exclusive, non-assignable, non-transferrable, terminable license to access, download and use the Font Software for your personal or commercial use for an unlimited period of time for free of charge. 
You may use the font Software in any media (including Print, Web, Mobile, Digital, Apps, ePub, Broadcasting and OEM) at any scale, at any location worldwide. 
You may use the Font Software to create logos and other graphic elements, images on any surface, vector files or other scalable drawings and static images. 
You may use the Font Software on any number of devices (computer, tablet, phone). The number of output devices (Printers) is not restricted. 
You may make only such reasonable number of back-up copies suitable to your permitted use. 
You may but are not required to identify Indian Type Foundry Fonts in your work credits. 
02. Limitations of usage
You may not modify, edit, adapt, translate, reverse engineer, decompile or disassemble, alter or otherwise copy the Font Software or the designs embodied therein in whole or in part, without the prior written consent of the Licensor. 
The Fonts may not - beyond the permitted copies and the uses defined herein - be distributed, duplicated, loaned, resold or licensed in any way, whether by lending, donating or give otherwise to a person or entity. This includes the distribution of the Fonts by e-mail, on USB sticks, CD-ROMs, or other media, uploading them in a public server or making the fonts available on peer-to-peer networks. A passing on to external designers or service providers (design agencies, repro studios, printers, etc.) is also not permitted. 
You are not allowed to transmit the Font Software over the Internet in font serving or for font replacement by means of technologies such as but not limited to EOT, Cufon, sIFR or similar technologies that may be developed in the future without the prior written consent of the Licensor. 
03. Embedding
You may embed the Font Software in PDF and other digital documents provided that is done in a secured, read-only mode. It must be ensured beyond doubt that the recipient cannot use the Font Software to edit or to create new documents. The design data (PDFs) created in this way and under these created design data (PDFs) may be distributed in any number. 
The extraction of the Font Software in whole or in part is prohibited. 
04. Third party use, Commercial print service provider
You may include the Font Software in a non-editable electronic document solely for printing and display purposes and provide that electronic document to the commercial print service provider for the purpose of printing. If the print service needs to install the fonts, they too need to download the Font Software from the Licensor's website.
05. Derivative Work
You are allowed to make derivative works as far as you use them for your personal or commercial use. However, you cannot modify, make changes or reverse engineer the original font software provided to you. Any derivative works are the exclusive property of the Licensor and shall be subject to the terms and conditions of this EULA. Derivative works may not be sub-licensed, sold, leased, rented, loaned, or given away without the express written permission of the Licensor. 
06. Warranty and Liability
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, INDIAN TYPE FOUNDRY MAKES NO WARRANTIES, EXPRESS OR IMPLIED AS TO THE MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR OTHERWISE. THE FONT SOFTWARE WAS NOT MANUFACTURED FOR USE IN MANUFACTURING CONTROL DEVICES OR NAVIGATION DEVICES OR IN CIRCUMSTANCES THAT COULD RESULT IN ENVIRONMENTAL DAMAGE OR PERSONAL INJURY. WITHOUT LIMITING THE FOREGOING, INDIAN TYPE FOUNDRY SHALL IN NO EVENT BE LIABLE TO THE LICENSED USER OR ANY OTHER THIRD PARTY FOR ANY DIRECT, CONSEQUENTIAL OR INCIDENTAL DAMAGES, INCLUDING DAMAGES FROM LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION NOR FOR LOST PROFITS OR SAVINGS ARISING OUT OF THE USE OR INABILITY TO USE THE PRODUCT EVEN IF NOTIFIED IN ADVANCE, UNDER NO CIRCUMSTANCES SHALL INDIAN TYPE FOUNDRYS LIABILITY EXCEED THE REPLACEMENT COST OF THE SOFTWARE. 
IF LICENSEE CHOOSES TO ACCESS THE FONT SOFTWARE THROUGH A CODE (API), IT MAY HAVE A DIRECT IMPACT ON LICENSEE'S WEBSITE OR APPLICATIONS. INDIAN TYPE FOUNDRY IS NOT RESPONSIBLE OR LIABLE FOR ANY INTERRUPTION, MALFUNCTION, DOWNTIME OR OTHER FAILURE OF THE WEBSITE OR ITS API.
07. Updates, Maintenance and Support Services
Licensor will not provide you with any support services for the Software under this Agreement.
08. Termination 
Any breach of the terms of this agreement shall be a cause for termination, provided that such breach is notified in writing to the Licensee by the Licensor and the Licensee failed to rectify the breach within 30 days of the receipt of such notification. 
In the event of termination and without limitation of any remedies under law or equity, you must delete the Font Software and all copies thereof. Proof of this must be provided upon request of the Licensor.  
We reserve the right to claim damages for the violation of the conditions. 
09. Final Provisions
If individual provisions of this agreement are or become invalid, the validity of the remaining provisions shall remain unaffected. Invalid provisions shall be replaced by mutual agreement by such provisions that are suitable to achieve the desired economic purpose, taking into account the interests of both parties. The same shall apply mutatis mutandis to the filling of any gaps which may arise in this agreement.
This contract is subject to laws of the Republic of India. Place of performance and exclusive place of jurisdiction for all disputes between the parties arising out of or in connection with this contract is, as far as legally permissible, Ahmedabad, India.
- 
Last Updated on 22 March 2021
Copyright 2021 Indian Type Foundry. All rights reserved. 

Binary file not shown.

93
site/css/fonts.css Normal file
View file

@ -0,0 +1,93 @@
@font-face {
font-family: 'Heading';
src: url('../assets/fonts/Saira/Saira_SemiCondensed-Light.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Heading';
src: url('../assets/fonts/Saira/Saira_SemiCondensed-LightItalic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Heading';
src: url('../assets/fonts/Saira/Saira_SemiCondensed-SemiBold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'BodySerif';
src: url('../assets/fonts/Rowan_Complete/Fonts/WEB/fonts/Rowan-Regular.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'BodySerif';
src: url('../assets/fonts/Rowan_Complete/Fonts/WEB/fonts/Rowan-Italic.woff2') format('woff2');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'BodySerif';
src: url('../assets/fonts/Rowan_Complete/Fonts/WEB/fonts/Rowan-Bold.woff2') format('woff2');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'BodySerif';
src: url('../assets/fonts/Rowan_Complete/Fonts/WEB/fonts/Rowan-BoldItalic.woff2') format('woff2');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'BodySans';
src: url('../assets/fonts/Open_Sans/OpenSans-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'BodySans';
src: url('../assets/fonts/Open_Sans/OpenSans-Italic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'BodySans';
src: url('../assets/fonts/Open_Sans/OpenSans-Bold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'BodySans';
src: url('../assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'Mono';
src: url('../assets/fonts/CommitMonoUnfancyDevNV143/CommitMonoUnfancyDevN-350-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Mono';
src: url('../assets/fonts/CommitMonoUnfancyDevNV143/CommitMonoUnfancyDevN-350-Italic.otf') format('opentype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Mono';
src: url('../assets/fonts/CommitMonoUnfancyDevNV143/CommitMonoUnfancyDevN-700-Regular.otf') format('opentype');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'Mono';
src: url('../assets/fonts/CommitMonoUnfancyDevNV143/CommitMonoUnfancyDevN-700-Italic.otf') format('opentype');
font-weight: bold;
font-style: italic;
}

23
site/css/index.css Normal file
View file

@ -0,0 +1,23 @@
@import url(fonts.css);
.font-body-serif body {
font-family: "BodySerif", serif;
}
.font-body-sans body {
font-family: "BodySans", sans-serif;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Heading";
}
code {
font-family: "Mono";
}
.container {
max-width: 800px;
margin-left: auto;
margin-right: auto;
}

3
site/index.dj Normal file
View file

@ -0,0 +1,3 @@
# VIOLATED ASSUMPTION
You're not meant to be here. How did this happen..?

1
site/ytheleus.org/assets Symbolic link
View file

@ -0,0 +1 @@
../assets

1
site/ytheleus.org/css Symbolic link
View file

@ -0,0 +1 @@
../css

Some files were not shown because too many files have changed in this diff Show more