So, I want to do something in agda, consider the following type:
data Genlist (A : Set) : Set wherecons : A -> Genlist A -> Genlist A
generator : ((tt : ⊤) -> Genlist A) -> Genlist A
So, I want to do something in agda, consider the following type:
data Genlist (A : Set) : Set whereOkay, we have this in Agda:
module I where A particular idiom kept appearing in Egel since I started using `|>` to form chains of transformations, I kept introducing an abstraction to set the chain up with an unknown initial argument.
I pondered on it for a while and introduced `do` syntactic sugar into Egel. The semantics of `(do f |> g |> h) x` is `x |> f |> g |> h` for example. That allows one to abstract from superfluous variables.
It works. Below, an example taken from Advent of Code '22.
# Advent of Code (AoC) - day 5, task 2
import "prelude.eg"
import "os.ego"
import "regex.ego"
using System
using OS
using List
def input =
let L = read_line stdin in if eof stdin then {} else {L | input}
val digits = Regex::compile "[0-9]+"
def parse_crates =
do map (do unpack |> chunks 4 |> map (nth 1))
|> transpose |> map (filter ((/=) ' '))
def parse_moves =
map (do Regex::matches digits |> map to_int
|> [{M,F,T} -> (M, F, T)])
def move =
[(CC,MM) -> foldl
[CC (N,F,T) ->
CC |> insert (T - 1)
(take N (nth (F - 1) CC) ++ nth (T - 1) CC)
|> insert (F - 1)
(drop N (nth (F - 1) CC))]
CC MM ]
def main =
input |> break ((==) "")
|> [(CC,MM) -> (parse_crates (init CC), parse_moves (tail MM))]
|> move |> map head |> pack
I am not sold on the donation, the abstraction also works as a strong visual reminder that a function is being expressed. But maybe it takes some getting used to. Also, it's a nice pun on Haskell monads and a reference to an old thought of mine that all you should need is function composition to chain actions, and that later became applicatives.
This is a short observation on 'the billion-dollar mistake' of Hoare, implementing null pointers in Algol W back in 1965. Dereferencing a null pointer usually causes a runtime error immediately terminating the program, and lots of programs crashed due to that.
This mistake is used ad nauseam to plead for safer languages, which made sense at the time since crashing programs had become the default. What is often not told is that runtime exceptions are standard and must be carefully handled in almost all languages. Let's take Haskell, one of the ostensibly claimed safest languages in the world.
Runtime exceptions can occur due to a variety of reasons, applying a partial function outside its domain is one of them. Let's try 'head []' in Haskell.
λ
> head []
No instance for (Show a0)
arising from a use of ‘show_M340108553800667339831401’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Show a => Show (Const a b)
-- Defined in ‘Control.Applicative’
instance Show a => Show (ZipList a)
-- Defined in ‘Control.Applicative’
instance Show GeneralCategory -- Defined in ‘Data.Char’
...plus 44 others
In the expression:
show_M340108553800667339831401 (let e_1 = head [] in e_1)
In an equation for ‘e_134010855380066733983140134010855380066733983140111’:
e_134010855380066733983140134010855380066733983140111
= show_M340108553800667339831401 (let e_1 = head [] in e_1)
In the expression:
(let
e_134010855380066733983140134010855380066733983140111
= show_M340108553800667339831401 (let ... in e_1)
in e_134010855380066733983140134010855380066733983140111) ::
String_M340108553800667339831401
That didn't go too well, Haskell cannot figure out the particular type instance for an empty list. Okay, let's add an assertion.λ
> let x = head ([]::[Int]) in x
*Exception: Prelude.head: empty list
And boom, there you have it. Haskell terminates with a runtime exception. In fact, any Haskell program can have this potential 'bomb' in it. While I slowly change a few lines in the Egel interpreter source code from time to time, I am thinking more about QM these days. For whatever reason. So, my braindead musings in all public light for people to laugh at below.
I couldn't help but think: QM is exactly what you get for describing 'spinning' or 'oscillating' phenomena with probability distributions.
The metaphor I have in my mind: Envision you're on a nice tropical island with a lighthouse. The light the lighthouse casts on the island is a spinning phenomenon. 50% of the time it faces you, 50% of the time it doesn't. The 'state', or rather 'behaviour', of that lighthouse can be described with a ket, and letting your hermitian loose on it will confirm that it's a 50/50 chance that you'll 'see' the light passing in front of you.
Now suppose you're on an island with two lighthouses, One lighthouse faces you 70% of the time, another 40% of the time. (The analogy with QM breaks here a bit but fix the behaviour of the lighthouses to fit your fantasy or understanding of QM.)
So when you make measurements of one lighthouse you'll know the probability distribution of the other lighthouse, without any 'spooky action at a distance.' I just don't see it.
ADDENDUM: These are indeed musings on Bell's inequalities. I agree with all that. But my idea is: Bell showed that there are no hidden variables, there cannot be a definite state satisfying the inequalities. What he didn't show was that there cannot be an 'oscillating' state (resulting in related probability distributions.)
ADDENDUM2: Dumbing it further down. Consider a fair coin, a ket faithfully describes: this is a system that once observed will have a 50/50 chance of returning heads or tails. Bell says there are no hidden variables in there. True, the system's behaviour, not state, is completely and faithfully described. Because there is no definite state until you flip it.
ADDENDUM3: The basic observation is that the difference between a superposition and an 'oscillating' state isn't that big. But where Bell says, reject local+real, I would say, local+real makes more sense so just accept that what you're studying is 'oscillating'. To make that stick is of course another issue.