Scrabble Oracle
Finds the best plays given a scrabble board and rack.
code demoFinds the best plays given a scrabble board and rack.
code demoA novel RPN stack language with guaranteed termination
code demoutf2 spec + cli
codeA witch must find her lost children in the forest.
code demoA roman and druid are friends
demoFalling sand simulator
code demoPrint-and-play board game. Recruit allies, collect artifacts, fight monsters!
demoOnline multiplayer AI competition
codePOC javascript multi-threading promise api
codeA minimalist dataflow programming language
codeWebapp for calculating the best Scrabble plays
codeYet Another Ray Tracer
codeMiniMaxable typeclass that uses negamax algorithm to solve simple zero sum games
codeCLI version control utility that syncs with Dropbox
codean ERC-721 inspired crypto collectibles Ethereum application
codea quick-and-dirty static templating CLI
codeA poor man's client-side templating engine
code demoa novel P2P approach to time release encryption
demoreal-time collaborative doodles
code3D 1st person puzzle game with novel time travel mechanics
code demodiff strings and lists with levenshtein distance
codecolor picker and discrete gradient generator
code demoa text editor in a petri dish
code demoA draggable, navigable, interactive synonym web map
code demoa paper that describes the math behind popular iterative fractals such as the Mandelbrot Set
demo
$ whoami
jake.wood
$ cat about.txt
Programming appeals to my creativity better than any other medium. Being a software engineer is like being a regular engineer except the builders work at the speed of light and the materials are free.
And that thing you made is also alive.
With this Frankensteinian power I make
- apps
- tools
- games
- art
Some of this is perusable on the "code" page.
Imagine you’re using JavaScript in a technical interview and the
interviewer asks you to implement fold. Acceptable response
vary depending on the interviewer’s programming values. Let’s look at
solutions that will most resonate with a few different personas:
Values getting the job done economically
function fold(arr, alg, init) {
return arr.reduce(alg, init)
}Pros
Cons
Values academic correctness
function foldr(alg, acc, xs) {
if (xs.length === 0) return acc
return alg(xs.at(0), foldr(alg, acc, xs.slice(1)))
}
function foldl(alg, acc, xs) {
if (xs.length === 0) return acc
return foldl(alg, alg(xs.at(0), acc), xs.slice(1))
}Pros
Cons
Values performance
function fold(array, callback, init) {
let acc = init
for (let i = 0; i < array.length; i++) {
acc = callback(acc, array[i])
}
return acc
}Pros
Cons
All 3 implementations have the potential to annoy 2 of the 3 interviewer personas and not because they’re not correct, but because they don’t align with what those interviewers think is important.
ok, so idea for interesting PL semantics.
concept: “lanes”
most programming languages are 1 laned in that they follow computation linearly. do this, then this, wait for this async to finish, do this, etc.
some programming languages have semantics for operating on 2 lanes.
for instance a promise chain in JS operates in 2 lanes. you follow the
then path until and error then you are shunted into the
catch path. In fact, catch is a specialized
railroad switch for shunting the results of lane 2 back to lane 1.
what’s even worse, track shifts are necessarily written vertically b/c
editors don’t handle writing different code horizontally.
anyway, here’s some syntax examples of what I’m thinking about.
So you’d write a bunch of functions (that cannot directly manage control flow) and you’d have a second syntax that describes the control flow, maybe something like:
func_a_lane1
func_b_lane1 | func_c_lane2
func_d_lane2
func_e_lane1 | | func_f_lane3
| func_g_lane2
those are all functions in a pipeline which accept data from 1 lane and return data to 1 lane.
so func_a_lane1 accepts data from lane 1 and might
return data to lane 3 which means it would pass result directly to
func_f_lane3.
contrived example:
goodness_test(number) {
if number == 4 return L1(number)
if number < 0 return L2(number)
else return L3(number)
}
this syntax is a superset of the famous Result aka
Either type but is more agnostic. it might be overkill but
also this isn’t really an explicit feature of any language I know so it
might be unexpectedly useful.
contemplating novel multi-tenant auth strategy:
every table has a many-2-many table with
auth_table
now if you want to query all boxes you can do
SELECT * FROM boxes
INNER JOIN auth_table AS auth ON auth.table_name = 'box'
WHERE auth.action = 'READ' AND auth.user_id = ?;
this has the interesting property that anything you can query through auth_table you’re allowed to query.
One ramification of this is that you could expose your DB to direct SQL queries by any user and the results could be filtered by appropriate auth_tables. User queries would be dynamically modified to include the auth join. If you wanted to get really wild you could do row-level security by adding a column_id field to the auth_table. You would need to think about DOS mitigation etc but still an interesting idea IMHO.
Initially I only had a fuzzy appreciation for Zig’s self-hosting problem/solution. After listening to the Software Unscripted podcast where they chatted with one of the Zig core team I feel like I have a better understanding of what’s going on which I will attempt to summarize here.
Zig is self hosted which means that if you have the latest zig compiler already you can compile any zig program (including the source code for zig compiler). If you don’t have the latest Zig compiler floating around you need a bootstrap compiler – i.e. a compiler not written in Zig that can compile the latest Zig compiler source code. The basic flow for adding features to Zig is as follows: Dev adds some new language feature X and compiles Zig with compiler U to produce compiler V. Zig compiler implementation is updated to use feature X via compiler V and compiled to produce compiler W. note: Compilers V and W are indistinguishable in which programs they can compile. compilers V and W can compile programs that U cannot. If someone else goes through these steps instead of you, then they have a copy of compiler V instead of you. If, after every step for every feature, the Zig team published a linux compatible version of Zig then anyone could stay up to date on Zig development. However, the Zig team doesn’t want to force people to use linux to bootstrap their Zig compiler (b/c developer experience is very important to Zig). This is the Zig self-hosting problem.
Well OK, why don’t they publish Zig on every OS after each step? The Zig team also doesn’t want to do that b/c it would take up a huge amount of storage (and $). Their solution is to basically do option 1, but instead of publishing an executable that runs on linux they publish a version of the Zig compiler that’s been transpiled to webassembly – the insight here is that every OS can run webassembly. The net result is that on a brand new machine, if you want the bleeding edge version of Zig (not an official release), you can download the webassembly bootstrap compiler (which is presumably updated frequently), download the Zig source code from github, compile that code with the webassembly compiler, and now you have the latest version of Zig without too much hassle.
(feel free to fact check me on anything)