Skip to content

Instantly share code, notes, and snippets.

View TyOverby's full-sized avatar
😸

Ty Overby TyOverby

😸
View GitHub Profile
@TyOverby
TyOverby / index.html
Created October 15, 2023 22:59
sample-viewer
<!DOCTYPE html>
<html>
<head>
<script defer src="./index.js"></script>
<style>
body{ overflow:clip; }
* {
padding:0;
margin:0;
background: #09141f;

Higher-order components

Now that you know what a component is, let's complicate things! If a component is "any ocaml value that returns a Computation.t", then a "higher-order component" is a component where one of the inputs is a component. Using this definition, some of the APIs exposed by Bonsai itself would qualify as higher-order components. Although not used very frequently, we export an "if" combinator defined like so:

val Bonsai.Let_syntax.Let_syntax.if_

Bonsai Patterns

"Components"

What is a "UI component" anyway? To me, "component" describes a grouping of code with the following properties:

  1. Abstraction: Users of the component shouldn't need to know about any implementation details
@TyOverby
TyOverby / var_t.md
Last active September 26, 2022 13:51

Never use Bonsai.Var.t inside an application

Bonsai is a framework for building incremental state-machines, so a big part of programming with Bonsai is managing stateful values. Sometimes this state is external: some data changes on a server, and it needs to get into the client so that the UI can update. But other times, the state is internal to the UI, tracking things like "content of textbox A" or "which row is focused in the table."

There are two primitives in Bonsai for dealing with state, and they correspond exactly to this distinction between "external" and "internal" state, and using them in the wrong place can lead to some pretty confusing bugs!

External State: Bonsai.Var.t

Bonsai.Var.t is intended to be used to inject values from outside of a Bonsai app into the computation. The API is quite simple

FROM ocaml/opam:alpine-ocaml-4.12@sha256:97d4da55048befbda12adc18765b049a9eb53a878bcce58dbfecb06f363273e8
# Set up user settings and install necessary packages
USER root
RUN sed -i 's-/home/opam:/sbin/nologin-/home/opam:/bin/bash-' /etc/passwd
RUN apk add git neovim libffi-dev gmp-dev zlib-dev openssl-dev
RUN mkdir -p ~/.cache/nvim
# As the main user
USER opam
type _ t =
| Return : 'a -> 'a t
| Bind :
{ t : 'a t
; f : 'a -> 'b t
}
-> 'b t
| Isolated : 'a t -> 'a t
| Map :
{ t : 'a t
open! Base
type binop =
[ `Add
| `Sub
| `Mul
| `Div
]
[@@deriving equal, sexp, compare, hash]
open! Core_kernel
open! Bonsai_web
open Bonsai.Let_syntax
open Vdom
module Model = struct
type t = int Int.Map.t [@@deriving sexp, equal]
end
module Action = struct

Problem

Given a directed graph with weighted nodes, find the a set of cycles that don't share any nodes, maximizing the total sum of the node weights. Ties can be broken arbitrarily.

Example 1

All nodes have weight 1

@TyOverby
TyOverby / dyn.md
Last active September 11, 2017 19:56
(define with-dynamic-var (sym val f)
    (define rec (f) 
        (match (reset (cons 'dyn sym) f)
            ({#finished, value} value)
            ({#shifted, {#lookup, cont}} (rec (thunk (continue cont val))))
            ({#shifted, {#mut, value, cont}} (with-dynamic-var sym value (thunk (continue cont))))
    (rec f))

(define lookup (sym)