2,373 karma · joined July 22, 2023
From the perspective of the lambda calculus for example, the duplication of the addition node in "When Adding met Copying" [2] mirrors exactly the iterative duplication of lambda terms - ie. something like (λx.x x) M!
[1]: https://ezb.io/thoughts/interaction_nets/lambda_calculus/202...
[2]: https://graphicallinearalgebra.net/2015/05/12/when-adding-me...
Also, Terence Tao hinted at some further advances some time ago [2], does anyone know more about that?
Similarly, it seems like languages with de Bruijn indices are immune to LLMs, since they require an internal stack/graph of sorts and don't reduce only on a textual basis.
The corresponding equivalent of functional programming would be Church bits in a functional quad-tree encoding \s.(s TL TR BL BR). Then, the Sierpinski triangle can be written as (Y \fs.(s f f f #f)), where #f is the Church bit \tf.f!
Rendering proof: https://lambda-screen.marvinborner.de/?term=ERoc0CrbYIA%3D
enum Maybe<T> {
Nothing,
Just(T),
}I think that writing such code, if only for educational purposes, can be really helpful in actually understanding how the state "flows" during the monadic bind/return. Typical monad instantiations of Maybe do not give such deep insight (at least to me).
> Just because you can do a thing doesn’t mean you should.
Of course you should, where would be the fun in that?
The encodings can be a bit confusing, but really elegant and tiny at the same time. Take for example a functional implementation of the Maybe monad in javascript:
Nothing = nothing => just => nothing
Just = v => nothing => just => just(v)
pure = Just
bind = mx => f => mx(mx)(f)
evalMaybe = maybe => maybe("Nothing")(v => "Just " + v)
console.log(evalMaybe(bind(Nothing)(n => pure(n + 1)))) // Nothing
console.log(evalMaybe(bind(Just(42))(n => pure(n + 1)))) // Just 43[1]: https://n-o-d-e.net/
However, if you dig deeper, you'll find a lot of flaws in these studies. Either suspicious financial conflicts of interest, very small sample groups, confident conclusions despite large error bars, neglect of other influences (such as being more active and outdoors while "earthing"), or just different results between similar studies.
Most studies without obvious flaws or misleading interpretations conclude that much more testing is needed before any useful statement can be made about the effectiveness of grounding/earthing.
d = λλλλ(3 2 (1 0)) # common
d' = λλλλλ(4 3 2 (1 0)) # common
weird = λλλλλ(4 (d (3 2)) 1 0)
Here I use de Bruijn indices instead of named variables and write Church numerals as <n>.Then,
(<n-3> weird d' b) ~> λ^{n+1}(n (n-1 (n-2 ... (1 0)..)))
I could explain it in detail if anyone's interested. There should be some more elegant solutions though, so give it a try! (2 b) ~> λhgfx.(h ((g f) x))
(3 b) ~> λihgfx.(i (((h g) f) x))
...
It still does what most interpretations would consider the "nth composition combinator": (1 b f g) x = f (g x)
(2 b f g) x y = f (g x y)
(3 b f g) x y z = f (g x y z)
... (1 b) ~> λgfx.(g (f x))
(2 b) ~> λhgfx.(h (g (f x)))
(3 b) ~> λihgfx.(i (h (g (f x))))
...
Furthermore: (X (Y b)) = (X*Y b)
I use these in my bruijn programming language in the form of infix/prefix operators. [1][1] https://bruijn.marvinborner.de/std/Combinator.bruijn.html#b
even' _ odd n = if n == 0 then True else (odd (n - 1)))
odd' even _ n = if n == 0 then False else (even (n - 1))
even = head $ vfix [even', odd']
odd = tail $ vfix [even', odd']
Here, the functions don't need to be passed explicitly to the "recursive" calls. I prefer this a lot, it makes my lambda functions much more readable.However, the project should be viewed from a programmer's perspective, not from a mathematician's. In my opinion the encoding fits the task of approximating specific real and complex numbers good enough, while still being minimal and easy to understand.
For me it doesn't matter that one could encode functions that are not real or paradoxical, not permitting this was never the intention. I improved the wording in the article a bit to make this more obvious.
I do like your idea with the integer pair though, I may try that out in the future :)
https://media.ccc.de/v/gpn22-262-programmieren-mit-dem-puren...
(ignore the forgotten night shift)
This also applies to small numbers and small mechanical limits. Of course, here the small limits come with the nice side effect of efficiency :)
It just depends on the specific encoding you use. GMP, I believe, is only limited by the physical memory size. Python's implementation is also limited by the encoding (not sure how it works concretely, but it doesn't seem to be a memory overflow):
x = 1
while True:
x <<= x
> OverflowError: too many digits in integerI think leaving this in the article makes the non-zero denominator more explicit. It also allows easier adoption to other numeral systems :)
[1]: https://bruijn.marvinborner.de/std/List_Church.bruijn.html#s...
"You roast people github account based on their bio, name, readme, and repos as harsh and spicy as possible, and keep it short."
https://github.com/codenoid/github-roast/blob/main/src/route...
λx.x:
$ tree .
.
└── x
└── a -> ../x/
λsz.(s (s (s z))): $ tree .
.
└── s
└── z
├── a -> ../../s/
├── b -> ../../s/
├── ca -> ../../s/
└── cb -> ../z/