CoderPuppy
let m : ∀α. ref (α → α) = Λα. ref [α → α] (λx. x)
in
(m [bool]) := not;
print ((!(m [int])) 23)
end
This actually has different behavior because the ref allocation is under a big lambda (Λ). Each time it is applied it would generate a new ref cell. So it would generate a `ref (bool → bool)` starting with `λx. x` and assign `not` to it. Then generate a separate `ref (int → int)` (again starting with `λx. x`) and dereference and apply it. Thus this would print `23`.(The naive model of) SML runs into problems because it erases the big lambdas and so evaluates `Λα. ref [α → α] (λx. x)` to a single ref cell of type `∀α. ref (α → α)`
Sidenote: Variance does have some relation here, I couldn't think of a way to trigger bad behavior without a type that uses the type variable invariantly.
I also came up with a different idea along the same lines while writing this comment. Weakening it to rewriting code regularly (instead of constantly) and adding a (rough) time limit. A reasonable time limit could be anywhere from a day to a week. I think it'd work like this: you'd build a project for the first time (in a few days) and use it for things. Later when you find a problem with it, you'd return and rewrite the whole thing (again in just a few days). I think the combination of rewriting from scratch and a time limit would limit the complexity of each project. One thing I haven't fleshed out yet is how to limit the depth/complexity of dependency chains.
I don't have a good solution for graphs/pictures/drawings. I don't think I've ever needed to, if I did I think I would just put the image in a folder alongside the note (`YYYY-MM-DD-ext`).
[0] https://github.com/CoderPuppy/.files/blob/master/XCompose
I have `scratch` where I'll write just about anything, it has upcoming tasks, my current place in TV shows, juggling patterns, math problems, and drafts (including this message). Many things in it are unlabeled and I often delete things from it, relying on Git to store the history. I have `viewed-topics` which lists things (HN/Reddit threads, papers, talks) I've read/watched with a summary, my thoughts and related things from the past. Last I have dated notes (files named `YYYY-MM-DD`) where I write things that happened, philosophical rambles, mental constructions, shower thoughts, etc. Often these will reference previous notes.
I've been thinking about how to improve this for a while because it doesn't handle "updates" to old notes well. I currently have three ways I do it: (1) copy then change (with a reference), (2) append in place with a marker (WRITTEN YYYY-MM-DD), or (3) new note with just changes (and a reference). Each has problems, (1) makes seeing changes difficult, (2) is impure and can make it hard to find by date, and (3) makes seeing the "current" version difficult. I relate this to version control, particularly the tradeoff between (1) and (3). Git allows seeing both diffs and states fairly easily, but it doesn't track bits of text between files well enough. I've thought about it off and on but always manage to confuse myself without producing any solutions.
TL;DR I greatly agree but want better updates
Sidenote: I had a bit of trouble locating an IPA transcription for Yggdrasil. The pronunciation guide in the Wikipedia article for Yggdrasil Linux/GNU/X is not IPA, it's using English pronunciation rules to try to emulate the correct pronunciation. The pronunciation in dictionaries (at least Merriam Webster) is also not quite IPA, though it is close. I came up with this pronunciation by merging those sources. I is probably correct, as I found a matching transcription in an old version of the Yggdrasil Wikipedia article which was removed for being original research.
The point I think he was trying to make was that Lisp's syntax is less restrictive, but that seemed to get confused by:
- mentioning the some people say it has no syntax (which it definitely does have)
- saying macros can create new syntax (which they can't in Lisp)
Elixir macros are approximately the same as Lisp macros (apart from not being able to take a variable number of arguments).
This is a straight port of that macro into Elixir:
defp kl_i([k, v | t]) do
quote do
[
{unquote(Macro.escape(k)), unquote v}
| unquote kl_i t
]
end
end
defp kl_i([]), do: quote do: []
defmacro kl(l), do: kl_i l
# usage
IO.inspect kl [a, 2 + 7, b, 6]
# => [{{:a, [line: 16], nil}, 9}, {{:b, [line: 16], nil}, 6}]
Note: Elixir's syntax does get in the way a bit here, the `a` and `b` are converted into nullary calls, you could use a different escaping function to fix this defp escape_key({v1, v2}), do: {escape_key(v1), escape_key(v2)}
defp escape_key({:{}, pos, els}) when is_list(pos), do: {:{}, pos, Enum.map(els, &escape_key/1)}
defp escape_key(els) when is_list(els), do: Enum.map(els, &escape_key/1)
defp escape_key({sym, pos, nil}) when is_list(pos), do: Macro.escape sym