Faster-than-Light memes 2024-04-17T17:35:16+00:00 https://faster-than-light-memes.xyz/ Benjamin Schwerdtner https://faster-than-light-memes.xyz/screencasts.html screencasts 2023-06-17T23:59:59+00:00 screencasts

ftlm

screencasts

Braitenberg vehicle 2 and 3 - fear, agression, love

See: Vehicles Overview, Fear, Aggression, Love

Making some cybernetic, organismic machine animal simulations using Quil and Clojurescript.

The most canonical Braitenberg vehicles. 2 sensors, 2 motors, ray sources in the environment and different wiring make different behaviour.

I will deploy this soon.

Life coding Emacs, Clojure, Meow, screencast, programming, cybernetics, code, animals, bio computing, braitenberg, vehicles, love, fear, aggression, explore, system theory, control theory, simulation, toy, fun, little animals

Quil first experiments

Probably way too lengthy. You can watch how I spent last Saturday :)

Clojure REPL driven development showcase

The fruits of Clojure I

Making a knowledge base database keyword extractor with open ai chat api.

https://www.youtube.com/watch?v=GcJgGy-dfvE

Primagen was recently checking out Uncle Bobs Clojure post, which did not mention the most important thing about Clojure. Interactive Programming is the big magic word my friends.

Related: Interactive Programming and Lisp overview.

#_(add-libs '{net.clojars.wkok/openai-clojure {:mvn/version "0.9.0"}})
(ns scratch
  (:require
   [clojure.java.io :as io]
   [clojure.set :as set]
   [clojure.string :as str]
   [clojure.java.shell :as shell]
   [wkok.openai-clojure.api :as api]))

(def api-key (memoize (fn []
                        (str/trim (:out (shell/sh "pass" "private"))))))

(defn make-chat-completion [messages]
  (api/create-chat-completion {:model "gpt-3.5-turbo-16k"  :messages messages}
                              {:api-key (api-key)}))

(defn resp->message [resp] (-> resp :choices peek :message :content))

(def extract-keywords!
  (memoize
   (fn [file]
     (-> (make-chat-completion
          [{:role "system"
            :content
            "Extract the most interesting, essential keywords from the text.\n\nYou output edn vector format.\n\nExample: [\"AGI\" \"Timeline\"]"}
           {:role "user" :content "Doc:"}
           {:role "user" :content (slurp file)}])
         resp->message
         read-string))))

(defn query [db key]
  (get db key))

(defn assert-keywords [db file extracted-words]
  (reduce (fn [res e] (update res e (fnil conj #{}) file)) db extracted-words))

(def the-db (let [db {}
                  kws (for
                          [file ["/home/benj/notes/20230126T094804--the-joy-of-clojure__clojure_code.org"
                                 "/home/benj/notes/20230707T090418--conversation-1__clojure.org"]]
                          {:file file :keywords (extract-keywords! file)})]
              (reduce (fn [db {:keys [file keywords]}] (assert-keywords db file keywords)) db kws)))

(comment
  (spit "the-knowledge-db.edn" (prn-str the-db))
  (read-string (slurp "the-knowledge-db.edn"))

  (->
   (assert-keywords {} "foo" #{:a :b})
   (assert-keywords "foo2" #{:a :c})
   (query :c)))

Keywords: Emacs, Lispy, emacs lisp, livecode, screencast, how to emacs, Clojure, REPL, showcase, openai api, chat gpt, programming, code editor

Advanced cider jack-ins

As answwer to this cider issue on github.

;; jack-in-cmd allows you full control over the command that starts the nrepl server process

(defun my-cider-jack-in-prompt-cmd (jack-in-cmd)
  (interactive "sJack in cmd: ")
  (cider-jack-in-clj
   (list :jack-in-cmd jack-in-cmd)))


;; I personally like to def a jack in function in elisp which I have somewhere,
;; for instance the readme of my project or dev.el

(defun ftlm-vehicles-make-nbb-nrepl-jack-in ()
  (interactive)
  (cider-jack-in-clj
   '(:jack-in-cmd "npx nbb nrepl-server"
                  :project-dir "/home/benj/repos/clojure/vehicles/")))

Keywords: Emacs, Lispy, emacs lisp, livecode, screencast, linux, rice, productivity, scripting, programming, Clojure, Cider, Clojurescript, Nbb, Babashka

Lispy how to to insert single brackets

A frequently asked question when using Lispy is how do I insert single brackets, quotes, parens?

The answer is quoted-insert, wich is bound to C-q by default.

It reads the next character and inserts it, bypassing your current keymap and such.

Keywords: Emacs, Lispy, emacs lisp, livecode, screencast, how to emacs, how to lispy, lispy tips, emacs tips

Repl into production example

Real world show case repl into production. This is the kind of thing where Lisp delivers.

Keywords: Emacs, stumpw, arch, Clojure, Datomic Cloud, AWS, EC2, discord bot, REPL, production, fun with computers

(let [server (nrepl/start-server
                :port 7000
                :bind "0.0.0.0"
                :middleware cider.nrepl/cider-middleware
                :handler cider.nrepl/cider-nrepl-handler)]
    (reset! nrepl-server server))

Now we want to make an ssh tunnel to this machine to port 7000 on the server machine

~/.ssh/config

Host support-bot-ec2
     HostName ec2-18-212-83-183.compute-1.amazonaws.com
     User ec2-user
     IdentityFile /home/benj/.ssh/ben-ec2-key-pair.pem
     LocalForward 7000 ec2-18-212-83-183.compute-1.amazonaws.com:7000

ssh

Opening the tunnel is as easy as:

ssh -i/path-to-key.pem -L 7000:ec2-X-X-X-X.compute-1.amazonaws.com:7000 ec2-user@ec2-X-X-X-X.compute-1.amazonaws.com where the X vals are your compute instances public DNS.

ec2

https://console.aws.amazon.com/ec2/v2/home?region=us-east-1

find instance find rules add inbound rule

failure modes

Network SSH p22: If your addresses are wrong, some error; if your path

to the pem key is wrong, quick auth error

Network TCP p7000: If you open up the ports on the wrong SG or source CIDER, etc., IIRW connection will fail quickly with some error, or silently after a long timeout

nRepl service: If you forget to start your nRepl server on the appropriate port, long timeout IIRW

Fast cider overlays

blazingly fast cider overlays and how I got them.

keywords: Emacs, performance, programming, fun, cider, clojure, eval, ovelays, fast, quick, zappy, blazingly fast

Bobscheme

Bobscheme page.

Now I made a thumpnail, woar!

I also figured out that I can share -> embed on youtube. Then the iframe works (see above link).

Real world web app screencast

Adding a google drive list feature to my Clojure, Scittle, Reagent, Reitit app.

Real life Clojure programming. REPL-driven development. Emacs, meow, lispy, Clojure, Clojurescript.

Goals

  • Show practical Lisp and Clojure programming, with Emacs
  • Show Emacs

I want to get good at explaining and showcasing what it means to program Clojure. What is repl-driven development, how to do it and how it presents itself to the mind? (its look and feel).

For instance,

  • evaluating little forms every 10 seconds.
  • Tricks like inline defs
  • Impressive stuff like live coding a whole app.

Currently, I still try out stuff and need to get over the initial awkwardness of making videos.

Frames of mind

I realized I have a completely different communication style when I present vs. when I try to develop. One of the next things to try is to actually present in a video. And then slowly bringing in more live coding maybe.

Role models:

  • The Primagen
  • System Crafters

Date: 2023-06-17 Sat 13:07

About
Contact
]]>
https://faster-than-light-memes.xyz/anonymous-commands-in-emacs.html anonymous-commands-in-emacs 2022-09-23T23:59:59+00:00 anonymous-commands-in-emacs

ftlm

anonymous-commands-in-emacs

Introduction

Generally, you do not want to make keybindings to anonymous lambdas. Here is the primary reason that comes to mind:

(describe-keymap
 (let ((m (make-sparse-keymap)))
   (define-key m (kbd "f") (lambda () (interactive) 'hi))
   m))

I get help buffer with this content:

Key             Binding
f		[closure]

It is not really useful to just get the info [closure] here.

add-hook

The same thing goes for add-hook. From the doc string:

FUNCTION may be any valid function, but it's recommended to use a function symbol and not a lambda form. Using a symbol will ensure that the function is not re-added if the function is edited, and using lambda forms may also have a negative performance impact when running `add-hook' and `remove-hook'

Some of the hooks functionality is meant for symbols.

Solution

Alias your function:

(defalias 'foo-a (lambda () (interactive) 'hi))
 (describe-keymap
  (let ((m (make-sparse-keymap)))
    (define-key m (kbd "f") 'foo-a)
    (define-key m (kbd "b") (defalias 'foo-b (lambda () (interactive) 'hi2)))
   m))
Key             Binding
b		foo-b
f		foo-a

Foo-b works because defalias returns the symbol.

defun

(defalias 'foo (lambda () (interactive)))

is essentially the same as

(defun foo () (interactive))

Result

I end up just using defun inline. Examples:

(add-hook
 'sh-mode-hook
 (defun mm/add-bash-completion () ...))
(mememacs/leader-def
  "pP" (defun mm/project-switch-project-find-file ()
         (interactive) ...))

After writing this post, I went and fixed the remaining add-hook lambas In my config.

Date: 2022-09-23 Fri 18:59

About
Contact
]]>
https://faster-than-light-memes.xyz/scittle-prints-itself.html scittle-prints-itself 2022-09-26T23:59:59+00:00 scittle-prints-itself

ftlm

scittle-prints-itself

Description of the crafting of a website. Up here.

Introduction

I was wondering about what is cool for a newcomer to coding. I love lisp and I think one of the real joys in programming is interactive programming. So if I find some way of communicating this magic, that would be great.

After my binaural beats adventure I feel like Scittle is an amazing tool so I want to try it on something bigger. So I had this idea of a Scittle website that prints its source code, then you update the code and get an immediate effect.

I wanted this to be my website so maybe a new team member can also go into the code and hack around.

Problem statement

  1. print your source code
  2. ability to update code
  3. no code editor in the browser (input field…) I am thinking getting this approximately non-clunky would be hard. Especially balancing the parens. I decided to go with a drag and drop area where you slurp in a file into the browser.
  4. This is not a Quine because it receives the source code as input

Some reagent code

I do some StackOverflow-driven development for a drag-and-drop area.

I needed to figure out how ondragover Event and friends translate with hiccup. Luckily the legendary question answerer @p-himik helped me out in the #clojurescript slack channel. Turns out that when I add :on-drag-over in the attribute map it works.

(ns main
  (:require
   [reagent.core :as r]
   [reagent.dom :as rdom]))

(defonce state (r/atom {:code-text ""}))

(defn drop-area []
  [:div#drop-area
   {:style {:margin-top "1rem"
            :height "10rem"
            :width "10rem"
            :background "Aquamarine"}
    :on-drag-enter
    (fn [event]
      (set! (.. (js/document.getElementById "drop-area") -style -background) "cyan"))
    :on-drag-exit
    (fn [event]
      (set! (.. (js/document.getElementById "drop-area") -style -background) "Aquamarine"))
    :on-drag-over
    (fn [event]
      (doto
          event
          .stopPropagation
         .preventDefault)
      (set! (.. event -dataTransfer -dropEffect) "copy"))
    :on-drop (fn [event]
      (doto
          event
          .stopPropagation
          .preventDefault)
      (let [file (->  (.. event -dataTransfer -files) first)]
        (->
         (.text file)
         (.then
          (fn [t] (swap! state assoc :code-text t)))))
      (set! (.. (js/document.getElementById "drop-area") -style -background) "Aquamarine"))}
   [:div
    {:style {:margin "1rem"
             :padding-top "2.5rem"}}
    "drop a file here"]])

(defn code-snippet []
  [:div
   {:style {:background "gainsboro"}}
   (:code-text @state)])

(defn my-component []
  [:div
   [drop-area]
   [code-snippet]])

(rdom/render [my-component] (.getElementById js/document "app"))

(comment
  (swap! state assoc :code-text "foi110"))

With this, I have a drop area for a file.

Wonderful thing: Updating state redraws the UI for us.

Evaluating (swap! state assoc :code-text "foi110") makes reagent 's magic take effect.

Fetch

I also want to show the default code on the first load. After some StackOverflow research, I determine fetch should work.

(->
 (js/fetch "main.cljs")
 (.then (fn [x] (.text x)))
 (.then (fn [x] (swap! state assoc :code-text x))))

Pretty print the code..?

At this point my website looks like this:

VU5LqMM.png

Figure 1: Halfway there. Sort of printing the source code now.

I want to do something where at least the white space is rendered.

After searching the web, I decide I need a <pre> tag to say it is preformatted. Also <code> sounds great.

(defn code-snippet []
  [:div
   {:style {:background "gainsboro"}}
   [:pre
    [:code
     (:code-text @state)]]])

Update the function, re-eval the rdom/render form. Boom I instantly look at my updated visuals. With cider, I can also call cider-eval-buffer, or cider-eval-file. I first had the background style inside the code tag, which did not have the look I wanted. I can hack on a piece of UI in isolation. Directly. Without any mental suspension time. It is great. It is how all coding should be.

Eval string

Now for the magic of updating the website with whatever you upload. First, I ask Borkdude on slack how to evaluate a string. -> You use load-string.

(load-string
 (prn-str '(js/console.log "hello")))

Says hello in the console.

I update my file drop handler with the side effect of loading the text:

(fn [t]
 (load-string l)
 (swap! state assoc :code-text t))

(Yes there is a syntax error in this snippet).

I add this to the bottom of the file to see if my code is evaluated:

(js/console.log "hello2")

Now loading silently fails when I upload my file, but the text updates.

So I evaluate this in isolation:

(load-string (@state :code-text))

Ah, I get an analyzer error about l not being defined or something.

I update my handler like this:

(try
 (load-string t)
 (swap! state assoc :code-text t)
 (catch js/Error _ (js/alert "That code does not work.")))

following Stew Halloway's example of binary error feedback. Either there is an error, or there is no error. Error messages are just bloat anyway.

console says:

hello2

Another piece in place, another hit of dopamine, wonderful coding moments.

Only fetch once

I update the fetch code like so:

(or
 (:code-text @state)
 (->
  (js/fetch "main.cljs")
  (.then (fn [x] (.text x)))
  (.then (fn [x] (swap! state assoc :code-text x)))))

I can do this because in Clojure everything is an expression and I can put expressions anywhere.

Make a big aquamarine rectangle into a small magenta rectangle

I want something on the eyes so I change the style of the drop area:

{:margin-top "1rem"
 :height "5rem"
 :width "5rem"
 :background "magenta"}

Drag and drop, and:

IUrSY7t.png

Figure 2: Visuals updated via dragging and dropping a source file.

In emacs: list-colors-display, nice. And drag and drop with dragon.

This contraption of course pales in comparison to having a REPL running. But the idea is that it is might useful to somebody that doesn't even know what a REPL is. And if you are a beginner and now you wonder what that REPL thing is. Here I try to make a list of how to get a dev setup.

Here is an idea I had and did not put into the initial version: Make an undo button. So that the user can go back in the history of the website

Codepen

An arguably more mature version of this is up on codepen.

A key difference is that my website prints its whole code. No machinery is hidden anywhere.

If I may say so I think this is cute.

Date: 2022-09-26 Mon 13:21

About
Contact
]]>
https://faster-than-light-memes.xyz/faq.html faq 2023-07-14T23:59:59+00:00 faq

ftlm

faq

What theme are you using?

Here it is:

https://github.com/benjamin-asdf/dotfiles/blob/master/mememacs/.emacs-mememacs.d/lisp/visual.el

Back then I knew of some subreddit full of magical mindscapes or something. I forgot.

Z9UDrTfwrGa89JgPw-CrtYbgO9WuZulccPJZfZbExC4.jpg?auto=webp&s=cd43fed947bdc62db92383ee75d50c44822493ff

I picked one I liked and started picking colors from there.

The principles of the mememacs-visuals theme are:

  • Magic fruit in a dark forest.

pretty show paren

To get a little extra flourish and show me (more or less) when I am at a special lispy position, I do:

(defun mememacs/lispy-set-faces ()
  (if
      (and (eq meow--current-state 'insert)
           (or
            (lispy-left-p)
            (lispy-right-p)
            (and (lispy-bolp)
                 (or (looking-at lispy-outline-header)
                     (looking-at lispy-outline)))))
      (set-face-attribute
       'show-paren-match
       nil
       :foreground mememacs-visuals/heliotrope
       :underline t)
    (set-face-attribute
     'show-paren-match
     nil
     :foreground mememacs-visuals/mint-bright-2
     :underline t)))

(setf
 show-paren-style 'parenthesis
 show-paren-context-when-offscreen nil
 ;; 'overlay
 show-paren-when-point-in-periphery t
 show-paren-when-point-inside-paren t)

(add-hook 'meow-insert-mode-hook #'mememacs/lispy-set-faces)
(add-hook 'meow-normal-mode-hook #'mememacs/lispy-set-faces)

Also possible with evil.

Alternatively, I would set show-paren-match to white. It makes it blink pretty!

How do you repeat keys so quickly?

I modify the x key repeat rate to the maximum.

Oh boi, once you have this you will not go back. See: A System Like Water.

Lispy how to to insert single [, {, ", (

A frequently asked question when using Lispy is how do I insert single brackets, quotes, and parens?

The answer is quoted-insert, which is bound to C-q by default.

It reads the next character and inserts it, bypassing your current keymap and such.

Date: 2023-07-14 Fri 11:14

About
Contact
]]>
https://faster-than-light-memes.xyz/small-and-friendly-errors-with-cider.html Small and Friendly Errors with Cider 2023-02-05T23:59:59+00:00 Small and Friendly Errors with Cider

ftlm

Small and Friendly Errors with Cider

Growing by removing is growing stronger.

Less obtrusive Cider errors for a quicker repl-driven experience and practice. How I came to like error overlays.

1gxO1dN.jpg

Figure 1: A rose plant growing, the sun and speed of light. The idea of a computer.

The Quick-Eval

Repl-driven development is a philosophy and practice that focuses on using a REPL (Read-Eval-Print Loop) to interactively evaluate code snippets and see their results immediately.

The key is the whole language is always there and being able to make small experiments to the point where it meshes with your thinking.1

A big part of the practice of Repl-driven development is something I am calling the Quick-Eval flow for this blog post.

  1. Modify source code sexp
  2. eval
  3. Repeat

I want to optimize this practice. The speed of 1-2-3 can easily go below 5 seconds and everything is possible here.

  1. By honing lispy2 skills and juggling those sexps.
  2. By smoothing out the edges of cider-eval.

This aspect of Repl-driven development, the Quick-Eval involves using the mind, the fingers, and the editor. It's like playing an instrument or learning a motor skill like juggling - it requires dedication and repetition to master the movements. But the beauty of this practice lies in the ability to customize the tool to fit your thought process, unlocking the limitless potential for effectiveness. Knowledge of the editor becomes a key to a world of endless detail, where you can continuously optimize speed, the expressivity of intent and precision. The goal then becomes programming at the speed of thought, making structural editing a superpower of the Clojure programming language. And with the power to shape Emacs into what you desire, the possibilities are truly endless.

Speed cubers deconstruct the minutia for their finger tricks. This means being explicit and thoughtful about what movements to do during the performance.

This blog post is about an aspect of 2, smoothing out cider-eval, by eliminating error popups.

Let it flow

The first time I saw a Clojure stack trace, I thought my computer is broken.3

(Ariel Alexa)

Alex Miller mentioned4 recently that Clojure error messages are designed to not include the stack trace by default.

A lot of these tools will automatically print the stack trace and the Clojure REPL never automatically prints stack traces […] It prints you like a 2 line error message. And you can ask for the stack trace if you want additional information. We intentionally don't show you that because usually most of that information is not useful to you.

Nice, sounds like less heavy error messages are something to try out!

Cider already has a minimalistic error feedback available:

(setq-default cider-show-error-buffer nil)

With this setting, we get a little overlay right next to our cursor when evaluating with error.

Xk7Lbc1.png

Figure 2: Emacs cider eval error overlay displaying a runtime error message

We achieve a more smoothed-out Quick-Eval flow.

The consistent presentation, regardless of the presence of errors, creates a smoother and more streamlined workflow. This helps keep the focus on the code and eliminates interruptions in the thought process.

My mind can stay in one place, focused on the code, without a wall of something was wrong disrupting my flow.

Sometimes you want to look at a stack trace

Ok *cider-error*, we can always stay friends.

I do not advocate throwing away the stack traces, at all. With REPL-driven development and Emacs we have the power to move fast, and decide to inspect the stack trace should we decide the info would be useful.

*e exists for inspecting stack traces. Also *cider-error* is still at our side, we still faithfully render our stack trace there.

A quick and precise pop lets us go to the error buffer when we decide to do so:

(defun mm/pop-cider-error ()
  (interactive)
  (if-let
      ((cider-error
        (get-buffer "*cider-error*")))
      (pop-to-buffer cider-error)
    (message
     "no cider error buffer")))

(define-key cider-mode-map (kbd "C-c E") #'mm/pop-cider-error)

There is also a cider buffer selection dispatch command:

(define-key cider-mode-map (kbd "C-c X") #'cider-selector)

cider-selector into x to bring up the error buffer.

Let's not jump to conclusions

With less auto-jumping, we move slowly and deliberately and call upon our tools when we decide to do so. In practice, this can mean we jump around at insane speed, but we do so controlled.

(setq-default cider-auto-jump-to-error nil)

Currently, if you interactively eval5 and you have a compile error, Cider jumps to the top of the file. This is because we do not track a file position during the eval and Clojure only sees a piece of string, not the file.

So the most important command, cider-eval, that I want to optimize for Quick-Eval, had a rough edge and now I smoothed it out.

Errors should be friendly

Who invented that errors are red and angry?

(set-face-attribute
 'cider-error-overlay-face
 nil
 :background "DarkGreen"
 :foreground "white")

Now I have these green and peaceful boxes that don't make my heart rate go up.

Errors are the normal, correct behavior of my program, certainly in the context of developing. Sometimes I even eval just to check that there is an error. This is what repl-driven development gives us. And it should not feel like doing something wrong.

Spartan feedback for load-file

Currently, if you load a file and there is an error, there will be little feedback. The lack of an eval result in the echo area is signaling an error.

The extreme: Just say Did not work

In Debugging with the Scientific Method, Stuart Halloway mentioned what I would be calling Red light, Green light error feedback. The system only indicates if something worked or not, but not what specifically went wrong.

A trick in emacs if you want text invisible is you set the foreground to the same color as the background:

(set-face-attribute
 'cider-error-overlay-face
 nil
 :background "DarkGreen"
 :foreground "DarkGreen")

P7cn70e.png

Figure 3: Emacs cider eval error overlay displayed as a full green block.

I was still seeing the error in the echo area. So I did a quick (setf debug-on-message "nothing") and found cider--display-interactive-eval-result calls message.

The visibility of the message is controlled by cider-use-overlays.

(setq-default cider-use-overlays t)

Lol, now errors are just green blocks and I do not see the error message anywhere. If that is better than getting the error message I cannot say yet.

Footnotes:

2

Or the pareidit-like editor capability of your choice

5

What I call interactive eval is cider-eval-last-sexp etc. As opposed to cider-load-file.

Date: 2023-02-05 Sun 10:50

About
Contact
]]>
https://faster-than-light-memes.xyz/intro-to-clojure.html intro-to-clojure 2022-09-12T23:59:59+00:00 intro-to-clojure

ftlm

intro-to-clojure

This is a small list of recources for getting into Clojure, for an intro into why I believe Clojure is powerful check: The Joy Of Clojure.

Introduction

Clojure is a modern, functional lisp with a fiercely convinced community and production orientation.

Start

I highly recommend Maria.Cloud, you can just go there and start coding. This is great for anybody that does not know yet x

Clojure is different

If you try to do the same things in Clojure that you know from Javascript or Python, this will not work. Embrace Clojure is different. You should not be a vegan searching for good cheese. Use an avocado instead.

A dev environment

Get prepared for your journey as a pilot of an alien spaceship. As a beginner I suggest either

Vs Code

Easy to make work. A great editor. You will not need to be ashamed of your choice. calva for vscode

Emacs

Strong affinity to hacker culture and a program that is more than a tool, but eventually an extension to your hands, heart, and mind.

Here is a config file I tried to make for beginners: https://github.com/benjamin-asdf/simple-easy-emacs

A framework by clojurians that might be just right for you: https://github.com/corgi-emacs/corgi

There is also doom and spacemacs that enjoy wide appraisal for their "out of the box" experience.

Nr 1 book for beginners

Slack

Meet nice people that are excited about the tech on slack. Seriously a lot of people hang there and answer beginner questions, everybody is welcome.

Other such lists

Carin is cool and has a funny picture of the emacs learning curve here: https://howistart.org/posts/clojure/1/

I like that they have a philosophy section mentioning Rich Hickey's talks this matters a lot to clojurians.

https://thoughtbot.com/blog/tips-for-clojure-beginners https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f https://www.clojurenewbieguide.com/

Date: 2022-09-12 Mon 20:23

About
Contact
]]>
https://faster-than-light-memes.xyz/lisp.html Lisp 2023-07-08T23:59:59+00:00 Lisp

ftlm

Lisp

[wip]

Clojure

Blog posts for non-Lispers

  • No Iterations
  • Immutability is better
  • Don't Brake Me, Man!
  • The Sanity Game
  • Calculations are sexy

When you start to feel the power of LISP, the feeling is so strong that it may overwhelm you. You may find yourself trembling with a strange sensation that you have never felt before. This is a common reaction among those who are just beginning to appreciate LISP. Some people call it "thrill", others call it "ecstasy". Whatever name you choose, it is a sign that you are becoming a true LISP hacker.

llama2-70B

For me, the thrill of lisp happened when code started feeling like a substance below my fingers. When there was a place where I wanted to think thoughts and suddenly I was allowed to think thoughts at that place and have the program grow in whatever spot in the multidimensional cake that it is. It is an endless journey for the Lisp hacker to discover what it is, for it is the endless openness and malleability of ideas that is the nature of what makes Lisp.

Ideas are a great building material.

Programs are allowed to simply be. The arbitrary limitation of having to restart the program to make a change is a tragedy.

It is the spirit of C, to be close to the computer. A bare-metal language for expressing the very substance of the computer itself.

It is the spirit of Lisp, to be close to the ideas. It is an indispensable step to take, to have a program grow in the dynamic content of itself. No AI program will be an AI program if you need to restart it to make a change. For it would not be an evolving, dynamic, self-modifying thing. It is the moment when you are done with computer science and you can start doing thought science. This step was taken by McCarthy in 1960.

Lisp is different. You cannot know how it is different before you have tried it yourself because it's different in a way that you have to discover yourself. What is joy for the programmer's heart? To have effects on the computer, precise, straightforward, frictionless effects. If the expression intimacy to the computer does not make sense to you, it is because you have not experienced what it means to program a system with deep interactivity. See No Iterations.

Batch-oriented programming is 60 years out of date and we still have to deal with it. It is another example of the whole field of software engineering not growing up. Simply embarrassing.

Imagine interactive computing didn't become successful and dominant for accidental reasons. There would be people talking about terminals and overlapping windows and buttons and mice and instant feedback. These people would be seen as esoteric.

And real, serious programmers and computer people would stamp punch cards.

Nothing in the world says that we need to stamp punch cards to do computing. It is these kinds of limitations of thinking, that open-mindedness and imagination enable us to take a step back from.

It is merely accidents of history, that made C and its derivate became the mainstream. Sadly, the mainstream is sometimes wrong. And we end up having to deal with less powerful languages.

This is not a small issue. This is an opportunity cost of humanity not growing up to the potential already available. Consider the internet. And consider interactive ("personal") computing. Are these not 2 ideas that change the world? This is tech that shines like the sun and changes everything.

Literally from the same birthplace of ideas, the ARPA community and early computer science pioneers also came interactive programming. My claim is that it is as big of a deal as interactive computing and the internet, too.

Lisp is called the Maxwell Equations of computer science, because it was discovered as the simplest expression of computer programs. Lisp is said to be the only language which is beautiful. Lisps syntax exists for a single purpose, to be out of the way. Because Lisp is about ideas the way programming is about ideas. This is why it will stay relevant, the same way that Newtonian mechanics will stay relevant.

If you don't know Lisp, you don't know what power in a programming language is. You think that all languages are roughly the same power and I agree with you. The mainstream C derivate languages you tried all look equally powerful from my perspective, too.

Lisp is a more essential form of programming. To the point where I feel like batch-oriented programming is something else entirely. These are 2 activities, normal programming and batch-oriented programming. Batch-oriented programming is more like having a battle with the computer until it does what I want. Interactive programming, on the other hand, is a crafting process. It is like having a piece of wood and forming it under one's fingers. It is like having a brush and painting on a canvas. The relationship between the craftsperson and the art piece is 1:1 and direct. This is essential to an actual creative and artistic process.

These kinds of blind spots contribute to the coldness, number-oriented and low-level math-like activity, which is the dominant general population's view of programming. But it is not what the soul of the computer is about.

The soul of the computer is a malleable, joyful and open-ended well-spring of creative expression.

This is simply missing in all mainstream batch-oriented programming languages1. You don't know what you don't know until you know what you didn't know.

Clojure is a Lisp implementation on the JVM with a strong focus on practicality. It was created by Rich Hickey, who is a software engineer, not an academic. Clojure is explicitly designed for general-purpose application development, allowing you to do everything you might do with Java or C++.

Lisp is capable, by design, of expressing programs that are about programs. Once you have a machine that is capable of being about ideas, you can have ideas about ideas. I think this is the fundamental universality of memes and ideas, which gives such a system an open future.

It is this open-ended future that mainstream languages are still missing to this day. They are bound to reinvent it, and by doing so will have implemented a Lisp.

Consider JSON, it comes from javascript being a scheme, a Lisp variant. The power of JSON is that you can abstractly talk about the content of your program. A program about lists and sets is more powerful than a program about customers and shopping carts. And everything nests, everything prints etc. Luckily, the lingua franca of our shared data has some of Lisp's sanity inside it.

The core idea of Lisp is that this content is the program itself. This is not a small wrinkle in the programming model. It's the move that gives it its open future.

Whenever somebody builds command interpreters of (JSON) data, they are implementing a Lisp (Greenspun tenth rule). Soon they will make interpreters that assert subroutines into their databases and they will slowly invent Lisp, 60 years after its discovery. I already wrote this language, it's called Bobscheme (see below).

The key to understanding Lisp is realizing that it's simply layers upon layers of abstraction. - Hal Abelson

Emacs is not just a text editor, it's an extension of your mind that's limited only by your imagination.

To appreciate Lisp and Emacs, one must unlearn the ordinary, and then relearn the extraordinary.

Lisp and Emacs have something in common – a deep, underlying assumption that the power of abstraction will conquer all problems. - Richard Stallman

Potential future blog posts

Immutability is better, Immutability is better, Immutability is better

Clojure has immutable data structures by default.

You might have read Brian Goetz's Java Concurrency In Practice.

Using immutable values frees the mind from worrying about what somebody else might do to it. And it gives us the chance to get concurrency and time right.

This is a huge deal. The Thing That Lets You Sleep At Night.

I had this where I was lying awake in bed and I thinking about some code I know is hard to understand. And I think about all the ways this might break. It was all written in a statically typed language. The safety of static types is a mirage, the safety of immutable values is solid and evident.

This is an immensely freeing experience that matters.

More REPL-Driven development, Emacs + Clojure in practice

Don't Brake Me, Man! - The Sanity Game

Clojure is the one ecosystem where we think about breaking somebody else's code and just don't do it.

  • Breakage is broken
  • In the software industry we are scared of updating our dep
  • In the npm ecosystem "dependency-free" is now a quality badge
  • left pad, talks about complexity etc.
  • Breakage is an embarrassing failure of the software industry
  • You gotta hand it to the Roc[?] ecosystem, at least they acknowledge the problem but I don't think figuring out the right way to do breakage is the way to go. I don't think that making brakage hard fixes the issue.
  • This is a cultural/social thing
  • The Clojure ecosystem is the only one that is sane about this.
  • Rich Hickey said Brakage is broken and now there is a culture of sanity
  • https://www.youtube.com/watch?v=oyLBGkS5ICk
  • In Clojure, we update with impunity for the most part.
  • Accretion is ok. Software is allowed to grow.
  • Breakage is not ok. Don't do it. Don't figure out a way to do it. Don't do this to other people.
  • providing context (return values, namespace members)
    • I give you more: OK, accretion
    • I give you less: breakage, not ok
  • requiring context (parameters)
    • I want more from you: breakage, not ok
    • I want less from you: ok, accretion, the less you need the more you are

    If your language doesn't allow for accretion, wtf?

    Rich Hickey is smart, has good taste and puts thought into how he wants to program.

Calculations are sexy

Functional programming is about being careful and sensual. Where are actions (side effects) in our code?

A pure function, a calculation, is timeless. It does not matter how often you call it. In Clojure functions are assumed to be calculations by default. And 90%+ of all vars is pure functions. [see code analysis talks]

Data > Calculations > Actions.

We try to first express ourselves in terms of data, then calculations, and only carefully, with consideration, we use actions.

What Did Smalltalk Have That I Don't Have?

One thing I am sure of is that I can mold Emacs and a Clojure REPL into anything that it was.

Bobscheme

Bobscheme is a scheme implementation on dotnet using JSON as code.

Its purpose is to make it obvious to non-lispers, who know what JSON is, to see what Lisp is.

And I have fun making screencasts of building my language.

Github

Why is Lisp not more popular?

Everything is the way it is because it got that way.

Computer science is still in its infancy. We are still figuring out left and right how to do things and what it is about. There was a time when Assembly was unpopular. There was a time when structured programming, like C, was unpopular.2

One of my intellectual heroes is Marvin Minsky.

And in the early 1950s for the first time, computers got enough memory so there was actually room to store new programs in them and some pioneers started in 1954, 5, 6 started experiments where they actually wrote programs that wrote new programs that would then run.

And this led to the development of certain languages which were very good at… In which you could write programs that would write in the same language so they could keep changing.

There was a lot of progress and by 1960 we had 2 major languages that were good at modifying themselves.

Unfortunately, these languages were a little bit unfamiliar to people who did not see the great power of programs that could change themselves

And the world was overtaken by other terrible languages like the famous C language or Fortran or Algol and so forth.

Which became universally popular and in which it is almost impossible to write programs that change themself. That is just the parenthesis.

The bad drives out the good, whose law is it? Gresham's law.

In modern software practice, we see this. I can't understand why this 35-year-old language called Unix is suddenly popular.

But the only thing I can think of is that the other operating systems got filled with so much garbage in the intervening years that nobody can deal with that. And it is not that Unix is the latest thing it is the last fossil that has not completely dissolved from the past. So they are starting over and as far as I can see they are starting over to make the same mistakes.

Youtube

In Inadequate Equilibria, Eliezer Yudkowsky explains in a very eye-opening way why societies end up in inadequate equilibria, Nash equilibria that are worse than other potential, better Nash equilibria.

Using Lisp is an odd thing, so it doesn't fit with the idea of best industry practices. See Paul Graham's Revenge Of The Ners talking about exactly this dynamic.

If you look for the next program's language, all kinds of people are excited about this or that (usually new) language or framework. You hear left and right people making plausible claims about why x or y technology is great.

It is not clear that an ancient, magical programming language would also be the most powerful at winning in that market.

It would have some advantages sure, like actually doing something different. But this would also come at the cost of it looking a bit unfamiliar.

More history:

But the safety of types!

  1. Static types simply don't matter so much.
  2. Static types are a tradeoff. I think those people ignore the effort and price they pay for having those types. There is a time and place where you want something made out of concrete. But for many things and many moments, I want to choose to have something more malleable. Lisp and Forth programs have been debugged while in space. Know the price you pay.
  3. You get intermittent rewards from the types helping you now and then. The reward pattern of gambling addicts.
  4. I have to grant it to the Haskellers, Elm, Roc and maybe Rust persons, that getting leverage from the compiler giving feedback sounds useful.

Datomic is a great database and it is written in Clojure. If somebody can write a database in a dynamic language, then what do you think you need types for?

It is something we have science on. Having a good night's sleep has a bigger effect on the amount of bugs you make compared to having static or not having static types. [which studies?]

Unless you are implementing a smart contract or something, it simply does not matter so much. There are way more powerful things a language can provide you.

Immutability, now here is somethihng that is self-evidently powerfully helping you to get programs right. Like the moon hanging in the sky. Static types? Its a belief system whether it helps you or not.

Interactivity, you know the difference between quick feedback and non-quick feedback. If you don't, I cannot take you seriously.

Eric Normand

[I will find the podcast episode where he is musing about this, something like:]

Like a slot machine addict, now and then you get a spritz of the types helped you.. and then you praise the types for helping, but you forget the tradeoff you paid for having them. And all those countless times they did not help.

Douglas Crockford

[Something along the lines of:]

.. You forget the pain that you are taking on with the types… .. in my feeling, it is not worth it. .. I am on the dynamic side of things.

Jack Rusher

They just don't matter so much. https://www.youtube.com/watch?v=8Ab3ArE8W3s.

Here, he talks about static types of functional languages:

I have not seen the programs in these languages have any fewer defects than programs in any other programming language that I use, modulo the ones with really bad memory allocation behavior.

If you're doing some kind of, you know, horrible cryptocurrency thing, where you're likely to lose a billion dollars worth of SomethingCoin™, then, yeah, you maybe want to use some kind of verifier to make sure you're not going to screw it up. But, that said, space probes written in Lisp and FORTH) have been debugged while off-world.

Rich Hickey

What is true of every bug found in the field? - It passed the type checker!.

From Simple Made Easy.

From Effective Programs - 10 Years of Clojure - Rich Hickey, Things you need to solve your problem:

At the top, there is the domain, your understanding of the domain etc. This is the stuff where real bugs come from, misunderstandings and so forth.

At the bottom, there are issues like typos etc. It just is not a big deal. These are small mistakes. Static types help you with stuff like typos and maybe sort of 1 level up from typos.

Richard Feldman

Richard Feldman is a static type of person doing Roc, Elm and a great software podcast called Software Unscripted.

Getting great feedback from the compiler about the errors you are doing at least sounds like the kind of thing that has a chance of being useful.

I really should be writing some Haskell, Elm, Roc and Rust to know for myself.

Weak arguments for strong types

That is you being lazy!

There could be an answer.

But I choose to spend my time on something more useful right now.

I want to have the safety of knowing my program works

Do you interact with mainstream software at all? Whatever they are doing to not have bugs doesn't work.

Good reasons for static types [wip]

  • Writing smart contracts

Silly parenthesis!

  • Are the thoughts you think not more important than the syntax of a language?
  • In Lisp, the verb is always at the front. Is the noun always at the front in Java?
  • Not every change is an improvement, but every improvement is a change. How would it look if Lisp is different? How would it look if there is a reason to call it the only language that is beautiful?
  • Show me a language that looks like all the others and call it special and I am suspicious. Show me a language that looks completely different (APL) and call it special and I am intrigued.
  • Is it not true that we are children compared to the territory of things we don't know yet?
  • Would it not be hybristic to think you know at this date and age what the syntax of a language should look like?
  • Is it not the person, who has programmed in both languages, that can make the judgment: which is better?
  • Is it not true that Vim bindings are unfamiliar but powerful?
  • Is it not true that even git is unfamiliar but powerful?

Many things in the world that are powerful are also unfamiliar at first. Language is a tool of thought. A language is like an instrument. It is not in the first 5 minutes of engaging with it that you will know its power.

Maybe I was just lucky and I discovered Emacs and hence Lisp early enough, so it never was an issue to me that languages would look differently. I just took it for granted that some look differently. And I never was stuck with this strange mental illusion to think to know what languages are supposed to look like. How limiting?

The landscape of possible languages, even the ones we already are exploring is like a continent, where you know but one valley. Here are just a few completely different relatively popular programming paradigms and languages:

  • Array-based languages: APL, J.
  • Logic programming: prolog, datalog, core. logic.
  • Stack-based languages: FORTH.
  • Erlang (heritage from Prolog, Smalltalk, Planner). A lang with fault tolerance at the center. Sometimes said to be process-oriented.

It is sometimes said that Lisp has no syntax, which is not entirely true because the order of things has meaning. But there is another fundamental thing about Lisp syntax and the form of Lisp. It exists to be out of the way. Because the form barely matters, what matters is the content. McCarthy discovered Lisp's syntax accidentally, by just writing the AST of that hypothetical language in his paper.

So he deliberately was not thinking about the source code syntax but about the ideas. But it turns out that just talking about the ideas is a simpler and better way to program. Really funny.

Ah, and since structural editing is fucking awesome anyway you don't want to go back to something more complicated afterward.

Common Lisp has annoyingly many parents

(let ((foo bar))
  foo)

This overload of () to mean different things, binding, application, … is fixed in Clojure.

(let [foo bar]
  foo)

In Clojure, [] is a syntactic hint that you are doing binding, it gets rid of annoying parenthesis and it makes everything super regular. Because I can think the same binding thoughts (Clojure has amazing destructuring support for its idiomatic, plain immutable collection objects) everywhere I see [].

REPL? Yea language x also has this

One hears that interactivity is at the center of what Lisp is about and says:

Python has a REPL.

Yeah there are things like edit and continue in lang x.

When you make a project, is the first thing you do start a REPL and then not kill the process for days until your project is done?

When I come to your project, can I fire up a REPL and jump into the program?

When you want to look at your program's state in production, do you REPL in and simply see?

No, I don't think so. Because the interactivity was not at the center, not at all.

Programming also is a concrete thing, with concrete activities and cultures. You can do everything sort of in all general-purpose programming languages. What is practical is guided by this culture and practices. To ignore this is simply being a nerd for no good reason. It is pretending to care about essentials, but ignoring that in the real world, practicality is essential, too.

And the irony of the situation. The one is deluding themselves into the dreamland of those great Python REPL and edit and continue lands, where stuff works great and it's the normal way to do things.

Who is the one being unpractical, then?

The Blub paradox

http://www.paulgraham.com/avg.html

Learning multiple languages is virtually a must. To see what is different, and what is the same. Because what is the same is the soul of the computer. Well, at least it's data structures, algorithms, and control flow, and not that much more. And what is different are idioms and styles and culture and emphasis.

The one that has tried multiple mediocre mainstream languages will have a "mature" feel of the relative power of languages. And conclude it is simply a matter of taste. That all are roughly equally powerful.

Because there are many languages with devoted followers, there is a market of people saying this or that language is the best…. You stop taking these people seriously because you have understood that all languages are the same, and it depends on the context of which tool to choose.

Now the Lisp devotee pronounces the superiority of Lisp 100x and 10000x to other languages. And all it does is make your bullshit sensors fire. You have a mental model of the power of general-purpose languages.

Way more powerful than Assembly. Who would be so crazy as to give up all that expressivity for writing Assembly? It would be insane to program Assembly because the power difference between the mainstream high-level programming language and Assembly is so massive.

If I say Lisp is to those default langs like those default langs are to Assembly; Do you see maybe why it is such a big deal for me? It is insane to me to give up this power.

The point of this website is to increase the surface area of idea space association lines that make a person check out Lisp and understand why it is a different language entirely.

Lisp is different from what you consider "normal" languages the way a spaceship is different from a hot air balloon. Flying Lisp is simply a different activity, with a different range of spaces where you can go.

Here is an Answer for why.

What in the world needs to look different for this to be true? It's an ancient magical language made for AI, made by imaginative, brilliant people. It looks alien and it is said to have been discovered. It has been called the Maxwell equations of computer science and it has not changed ever. For if you change it, you simply end up with another dialect of it, because its ideas are at the bottom.

It is mentioned as the one language that changes your taste. That makes you understand what power means.

Programming is wizardry, but the magic is real. How sad, to not be excited enough about magic so you don't look into ancient lore of powerful alien technology.

Fixing the BBM

https://www.marktarver.com/bipolar.html

This is an existential blog post, so my answer is existential, too.

Yes, culture is simply off.

But what do you gain from getting depressed and lethargic from that? For me, this is simply another call to action. Simply another edge for which there is still a challenge to overcome.

Reality is not a video game, where you only get challenges that you can live up to.

Reality is not a video game, where all the challenges you get are proper, not in any sense and not even a little.

If culture is off, you don't get to complain that if only people listened….

If only people listened, we would be exploring the stars many times over right now.

So either you put people into the navigation problem you are solving, or you are making yourself blind to the world. Like somebody that goes through the motions of making some mistake, chasing some unattainable appearance of what, consistency? Like somebody who was tricked into thinking reality is a video game, and when its challenges are unorthodox, they pretend to not get it.

If reality is posing you a challenge and don't you live up to it; You die.3 We either fix humanity, despite all its problems, or we die.4

If you go forth and you think getting a university degree is equal to navigating the world. You are making the mistake of being a blind video gamer. You pretend there is a pre-allocated set of challenges to overcome for you to contribute to the world. But then you realize that university is part of culture, just like anywhere else.

The problem is not culture, the problem is not the many people in science are in for their careers. The problem is not the uselessness of money. Or the uselessness of hanging out with friends just for the sake of it.

The problem is you mistook the open-ended set of solution spaces for fixing the world with this pre-defined list of things to do. And then the fakeness and uselessness of it all crushes you to the ground.

More rambling

No IQ Tests

The many little ways in which we make software a puzzle. And how we can fix this.

  • Rembering operator precidence by heart, juggling numbers and < and > in your head. That's little puzzles, not programming.
  • Guys (mostly) enjoy the puzzle of it and mistake it for programming. That is a mistake.
  • Imperative programming inherently makes you keep track of those little places in your head.
  • Don't do this to yourself and others, it is pain and it is not programming, it is too low level.
  • Fix 1: interactive programming. I never think about how < works. I just try with some example inputs until it does what I want.

    This is like programming with clay. Just touch it with your hands and form it into what you need. See Interactive Programming.

  • Fix 2: Everything immutable values, everything pure functions. Except in the small places you need it.

    You don't know the amount of mental distress you suffer until you have programmed in a language where immutability is the default. Seriously, this is like some annoying sound in the background for years and you don't notice. Once it's gone you realize how much it was bothering you.

    Data is simpler than calculations which are simpler than actions. And you need very little action to make a machine go. Datomic is a database that has one single reference cell compare and swap thingy. One.

  • I wonder what the next-gen higher levels of programming will be.

    When I feel myself into software and wonder what are the next things, then I think of putting all the code, the symbols of a system into a database, and having it evolve and queriable etc. by itself. It would be the ultimate dynamic Von Neuman Machine. Then the whole system would become one level more like clay. But with history like in git.

Quotes

Footnotes:

1

Javascript is sort of the odd one out. Because it is a Scheme (a functional, academic, tiny lisp dialect).

In JS, you can very dynamically build the program while it runs. Not sure if people are doing it so much, but it has this power.

2

Bob Martin has a story somewhere where he tries to convince his coworkers, who used Assembly, to use C.

3

That is from Eliezer Yudkowsky.

4

In the "best world" limit, this means all the people dying from disease, aging and poverty, could live in a space-faring utopia right now.

In the worst world, this means we either avoid extinction events, or we don't.

Date: 2023-07-08 Sat 09:54

About
Contact
]]>
https://faster-than-light-memes.xyz/zappy-cider-eval-overlays.html Zappy Cider Eval Overlays 2023-07-13T23:59:59+00:00 Zappy Cider Eval Overlays

ftlm

Zappy Cider Eval Overlays

Cider eval overlays are a great technology of our time. Being able to use the hands and the eyes just in the place where I am thinking, right in the source code - just invaluable.

I want the The Quick Eval smooth and zappy. Yea. Pure coconut. It is my skates with which I ride the ice of the Clojure program.

How to get really fast cider eval overlays.

The Benchmark

  • Make a cider-eval-last-sexp after this form:
(repeatedly 10000 random-uuid)
  • is it zappy, or not zappy?

Numero Uno

The biggest gain - or pain, depending on how you want to think about it is the echo area message.

I set cider-use-overlays to t, not both.

(setq-default cider-use-overlays t)

Now we do not print the message anymore which is a night and day difference.

cider–make-result-overlay perf hacks

I still am not completely satisfied with those overlays. You might think that fontifying the string takes long but it seems like in my perf investigation that did not seem to be an issue. (Hence have cider-overlays-use-font-lock to t).

length instead of string-width

I went into cider--make-result-overlay and one of the performance bottlenecks was that we called string-width on those large strings, which is an expensive computation.

It needs to calculate the actual string display width, which is different from the character count of the string. I just changed this to a length call. Doesn't matter much to me. It's just about saying when to cut off the result-overlay.

This does another little speed up.

In case you don't know.

  • profiler-start
  • do the action you want to debug
  • profiler-stop
  • profiler-report

Truncate after 1 line, not 3 lines

I am fine with rendering less data in the preview overlay. I can use cider pretty print for bigger outputs. Instead of cutting off after (* 3 (window-width)) I just cut off after 1 window-width.

Here is the updated function that I use:

;;; cider-overlays.el --- Managing CIDER overlays  -*- lexical-binding: t; -*-

;; Copyright © 2015-2023 Bozhidar Batsov, Artur Malabarba and CIDER contributors

;; Author: Artur Malabarba <bruce.connor.am@gmail.com>

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.


  (cl-defun cider--make-result-overlay (value &rest props &key where duration (type 'result)
                                                  (format (concat " " cider-eval-result-prefix "%s "))
                                                  (prepend-face 'cider-result-overlay-face)
                                                  &allow-other-keys)
        "Place an overlay displaying VALUE at the position determined by WHERE.
      VALUE is used as the overlay's after-string property, meaning it is
      displayed at the end of the overlay.
      Return nil if the overlay was not placed or if it might not be visible, and
      return the overlay otherwise.

      Return the overlay if it was placed successfully, and nil if it failed.

      This function takes some optional keyword arguments:

        If WHERE is a number or a marker, apply the overlay as determined by
        `cider-result-overlay-position'.  If it is a cons cell, the car and cdr
        determine the start and end of the overlay.
        DURATION takes the same possible values as the
        `cider-eval-result-duration' variable.
        TYPE is passed to `cider--make-overlay' (defaults to `result').
        FORMAT is a string passed to `format'.  It should have
        exactly one %s construct (for VALUE).

      All arguments beyond these (PROPS) are properties to be used on the
      overlay."
        (declare (indent 1))
        (while (keywordp (car props))
          (setq props (cdr (cdr props))))
        ;; If the marker points to a dead buffer, don't do anything.
        (when-let ((buffer (cond
                       ((markerp where) (marker-buffer where))
                       ((markerp (car-safe where)) (marker-buffer (car where)))
                       (t (current-buffer)))))
          (with-current-buffer buffer
            (save-excursion
              (when (number-or-marker-p where)
                (goto-char where))
              ;; Make sure the overlay is actually at the end of the sexp.
              (skip-chars-backward "\r\n[:blank:]")
              (let* ((beg (if (consp where)
                              (car where)
                            (save-excursion
                              (clojure-backward-logical-sexp 1)
                              (point))))
                     (end (if (consp where)
                              (cdr where)
                            (pcase cider-result-overlay-position
                              ('at-eol (line-end-position))
                              ('at-point (point)))))
                     ;; Specify `default' face, otherwise unformatted text will
                     ;; inherit the face of the following text.
                     (display-string (format (propertize format 'face 'default) value))
                     (o nil))
                ;; Remove any overlay at the position we're creating a new one, if it
                ;; exists.
                (remove-overlays beg end 'category type)
                (funcall (if cider-overlays-use-font-lock
                             #'font-lock-prepend-text-property
                           #'put-text-property)
                         0 (length display-string)
                         'face prepend-face
                         display-string)
                ;; If the display spans multiple lines or is very long, display it at
                ;; the beginning of the next line.
                (when (or (string-match "\n." display-string)
                          (> (length display-string)
                             (- (window-width) (current-column))))
                  (setq display-string (concat " \n" display-string)))
                ;; Put the cursor property only once we're done manipulating the
                ;; string, since we want it to be at the first char.
                (put-text-property 0 1 'cursor 0 display-string)
                (when (> (length display-string) (window-width))
                  (setq display-string
                        (concat (substring display-string 0 (window-width))
                                (substitute-command-keys
                                 "...\nResult truncated. Type `\\[cider-inspect-last-result]' to inspect it."))))
                ;; Create the result overlay.
                (setq o (apply #'cider--make-overlay
                               beg end type
                               'after-string display-string
                               props))
                (pcase duration
                  ((pred numberp) (run-at-time duration nil #'cider--delete-overlay o))
                  (`command
                   ;; Since the previous overlay was already removed above, we should
                   ;; remove the hook to remove all overlays after this function
                   ;; ends. Otherwise, we would inadvertently remove the newly created
                   ;; overlay too.
                   (remove-hook 'post-command-hook 'cider--remove-result-overlay 'local)
                   ;; If inside a command-loop, tell `cider--remove-result-overlay'
                   ;; to only remove after the *next* command.
                   (if this-command
                       (add-hook 'post-command-hook
                                 #'cider--remove-result-overlay-after-command
                                 nil 'local)
                     (cider--remove-result-overlay-after-command)))
                  (`change
                   (add-hook 'after-change-functions
                             #'cider--remove-result-overlay
                             nil 'local)))
                (when-let* ((win (get-buffer-window buffer)))
                  ;; Left edge is visible.
                  (when (and (<= (window-start win) (point) (window-end win))
                             ;; Right edge is visible. This is a little conservative
                             ;; if the overlay contains line breaks.
                             (or (< (+ (current-column) (length value))
                                    (window-width win))
                                 (not truncate-lines)))
                    o)))))))

Date: 2023-07-13 Thu 20:24

About
Contact
]]>
https://faster-than-light-memes.xyz/getting-around.html getting-around 2023-10-01T23:59:59+00:00 getting-around

ftlm

getting-around

See Intro Page.

Vehicle I - Getting Around

Here is the Code if you want.

Watch them go!

You can also click on the screen to move the temperature bubble and see the effect.

With this link you get a leva control panel to modify some paramaters.

Some of these (warning, link will open a tab with flashing lights) I was building while listening to the finest Berlin techno.

Function

Cart number one has 1 motor 1 sensor and 1 connection.

Braitenberg asks us to imagine it having a little Brownian motion so it doesn't get stuck.

Otherwise, the sensor senses high temperature and makes the motor go. The motor moves it forward without rotating (this will change in vehicle 2). This animal then stays in areas of low temperature and moves away from high temperature.

I have to say this whole pond thing really went somewhere. My world is sort of this microscopic world of little animals, darting around and getting excited by some bubbles flying around.

They sort of have 2 modes, being indecisive and wobbling around a bit, or they dart around.

Trippy vehicle number 1 getting excited by disco bubbles, bouncing of walls and finding the few dark spots on the canvas.

They all fly away when you scroll the screen away right now but you can reload the page to get it back

The first part is an intro, then lengthy engineering, and in the end first version of the vehicle's number one microscopic animal bubble world:

Form

Each Braitenberg vehicle is described by:

  • env
  • body
  • sensors
  • effectors
  • brain (connections)

Body Is synomous with cart for my purposes. For now, my body is represented with this rounded rect. The body moves around, depending on the forces acting on it.

Let cart-1 be:

(defn cart-1
  [{:keys [pos scale rot color shinyness]}]
  (let [sensor (->sensor :top-middle)
        motor (->motor :bottom-middle)
        line (->connection sensor motor)
        body (assoc (->cart pos scale rot color)
                    :components (map :id [motor sensor])
                    :motors (map :id [motor])
                    :sensors (map :id [sensor])
                    ;; particle means it has brownian motion
                    :particle? true
                    ...)]
    [body sensor motor line]))
Some green little round vehicle #1

Sensors have an activation based on the env. I also gave it a modality ('Temparature' for now, light, smell etc. later).

Sensors are circles in my world.

The temperature sensor has the environment as a parameter and changes the activation of the sensor:

(defmulti update-sensor (fn [sensor _env] (:modality sensor)))

(defmethod update-sensor :temp
  [sensor env]
  (let [temp (->temp (position sensor) env)
        sensitivity 10
        activation (* sensitivity (max 0 temp))]
    (assoc sensor :activation activation)))

A body experiences "force" depending on its effectors. (effors == motors for the moment).

(defn update-body
  [cart state]
  (if-not (:cart? cart)
    cart
    (let [effectors (effectors cart state)]
      (-> cart
          (update :acceleration + (reduce + (map :activation effectors)))
          (assoc :angular-acceleration (reduce + (map effector->angular-acceleration effectors)))))))

Later, motors are not only :bottom-middle, but left and right. Thereby rotating the cart by their action.

The only thing missing to make it go is a connection between the sensor and the motor.

(defn ->connection
  ([a b] (->connection a b identity))
  ([a b f] {:source a :destination b :f f}))

An abstract connection in my world has a source, a destination and a transduce signal function f. I am happy I found the name source and destination for these. The Sender and receiver sounded like they were talking over the radio and some other ideas by GPT were controller and controlled or such. I did not want to limit my thinking towards either one of them being more important than the other.

So source and destination. Both sound so wonderfully important. Just right.

The meat of the signal transduction is transduce-signal.

(defn transduce-signal [destination source {:keys [f]}]
  (update destination :activation + (f (:activation source))))

With the current choices I made, the activation of the destination is updated accumulatively sort of. f is allowed to return a negative number, thereby making the connection inhibitory.

The difference between my model and a McCulloch-Pitts neuron is:

  • f is allowed to be any function. Including shelling out or querying a database, not just weight. Both models allow the input functions to be excitatory or inhibitory.
  • I don't have theta (θ), the threshold. My neurons are simply gradually activated.
  • My activation is modeled as a number, activation. Allowed to be any number. In neurophysiology, this activation is encoded in the rate of the neuron firing.
  • In a McCulloch-Pitts neuron, on the other hand, a neuron is either on or off.

I decided to draw the connection on the screen as a line.

Then I went and I gave all the entities with activation a color shine, depending on the activation.

(defn activation-shine
  [{:as entity :keys [activation shine]}]
  (if activation
    (let [shine (+ shine (* *dt* activation))]
      (assoc entity
        :shine shine
        :color (q/lerp-color (q/color 40 96 255 255)
                             (q/color 100 255 255)
                             (normalize-value-1 0 1 (Math/sin shine)))))
    entity))

It lerps the color between cyan and yellow. And it is faster when the activation is higher.

This, I have to say, turned out amazingly cute and gives my whole simulation its unique flair.

When a vehicle finds a high-temperature bubble, it starts blinking like crazy and moves straight away.

Check # 10 with really hot temp bubbles. Comes across like they completely vibrate from that!

Isn't there something deep about the honesty of this animal in a way? We see all its functioning, all its desires and purposes and its inner workings, its brain. Everything there is in the open.

Certain animals are coming to mind, namely cuttlefish and octopi. They have a special structure in their skin that makes them able to change color via muscle input.

A video: OCTOPUS Camouflage | Changes color, texture and shape.

This book is quite amazing: Other Minds: The Octopus, the Sea, and the Deep Origins of Consciousness.

Godfrey-Smith had this hypothesis, how cuttlefish are perfectly signaling their internal states, without any message. No communication because nobody is there to interpret. Because cuttlefish are colorblind themselves. Except when they camouflage or hypnotize prey I suppose.

Date: 2023-10-01 Sun 17:19

About
Contact
]]>
https://faster-than-light-memes.xyz/generative-art.html generative-art 2023-09-10T23:59:59+00:00 generative-art

ftlm

generative-art

I want to do some visualizations and generative art using Clojure. One of my goals is to make a play-through and simulate Braitenberg vehicles.

I spend time trying to do some geom, which is a really advanced lib with which you probably can do really a lot. All the examples are sort of on the edges of what you can do with the thing, so not much beginner material in the examples. Graphics and OpenGL bring together multiple high-ceiling topics: math, geometry, 3D tech, and shaders (GPU programming).

One day I will speak this language well enough so I straightforwardly know how to make a damn red triangle. Eventually, I would like to code shaders like Sebastian Lague in this crazy inspirational slime mold simulation thing.

I also tried to generate some SVG, also with geom but realized for the kind of stuff I want to do, I probably want to be more in the direction of a game engine kinda of world with update logic, instead of declaratively say the animations.

I want to make toys and game-like things. For the moment I leave both the 90s svg forms stacking approach, as well as a 3D/pixel/shader approach for another time.

I decided quil looks like it has a low floor and a high ceiling, so let's go.

Brownians

brownians #20

The Brownian world is my first generative art algorithm toy simulation world.

Current code, art gallery.

I came across Tyler Hobbs and decided his stuff is really cool. I started skimming probability distributions for algorithmic artists and decided I needed Gaussian Bell curves in my algorithms.

When you do biology, biochemistry and these things, almost all relationships are expressed in normal distributions a.k.a bell curves. Or as overlapping bell curves from multiple factors. Say the height of plant genotype, the count of blood cells in a sample, and the reaction times of a human.

normal distribution

It only has 2 parameters, the mean and the standard-deviation.

With the mean, I move the curve left and right, with the std-deviation I make it taller or flatter. q/random-gaussian returns a Gaussian random number with a mean of 0 and standard deviation something - So the return values are between -1 and 1.

Quil:

(defn normal-distr [mean std-deviation]
  (+ mean (* std-deviation (q/random-gaussian))))

Clouds

If I spawn circles in a 2D rect using a normal distribution, I get a natural-looking cloud.

Circles in a cloud, brownians #22

spread

ChatGPT helped generate some code that made them fly away from the center.

I control it with the :spread-speed control parameter of the Brownian world.

High spread-speed setting in brownians #5

Little motions… Brownian motion!

I think I want to make the wobble around and I realize, I really want some Brownian motion algorithmic cakeness in my world.

I am not sure how accurately this is of a simulation, but making the velocity of my circles change in a normal distribution way, where 0 is the mean and they wiggle in the other directions else.1

(defn brownian-motion [entity]
  (let [brownian-factor (:brownian-factor (controls))]
    (update entity :velocity (fnil (fn [[x y]] [(+ x
                                                   (* brownian-factor (q/random-gaussian)))
                                                (+ y
                                                   (* brownian-factor (q/random-gaussian)))])
                                   [0 0]))))

Well, I was very satisfied with the result. So much so that I called the whole toy world and the resulting art gallery brownians.

No spread-speed, but high brownian-factor - brownian #23

Ah brownian-factor I could have called temperature. Now the term absolute zero makes absolute sense. Brownian-factor cannot get lower than 0. Yes, the way they are flying reminds me very much of physics/chemistry simulation gifs of these things.

Simulating infection

I added an attribute infectable? to my circles and made some of them spawn infected. Then I make some temporary lines between 2 random infected and non-infected circles. With a normal distribution, the non-infected now too becomes infected. With full disregard for all prior art on epidemiology, there is a normal distribution in play!

I have controls infected-rate, how many circles spawn infected, :infectiousness makes it spread faster, :infected-color and :infected-transform changes the appearance of infected ones.

Defaults with red infection circles brownian #24

Now you can look at this and see an abstract graph. This could be friends in a network with an idea spreading. A computer virus jumping between computer nodes. Or the dankest meme conquering the internet.

I played around with the controls and put some into a gallery. The code for the gallery is here.

Screencast

Probably way too lengthy. You can watch how I spent last Saturday :)

Footnotes:

1

The Wikipedia article has quite some equations.

Seems like the particle distribution follows, unsurprisingly, a normal distribution. I think my circles are quite close to this.

Most stay where they spawn and some fly off.

Date: 2023-09-10 Sun 18:10

About
Contact
]]>
https://faster-than-light-memes.xyz/minds-and-machines.html minds-and-machines 2023-06-25T23:59:59+00:00 minds-and-machines

ftlm

minds-and-machines

This blog post is a draft version of what then became No Iterations

Continue at your own peril.

lisp_cycles.png

This blog post is for me.

For the version of me that didn't look into Lisp and just did not know.

Lisp and its most modern and practical dialect, Clojure are widely regarded as the only language that is beautiful.1

They are often described as powerful, elegant, minimal.2 and joyful 3

What moves these people to make such claims?

Reality does not by itself reveal its inner workings to you. You only see little glimpses and pieces of it. Your job as a scientist, coder or wizard is to use your imagination of how these pieces can fit together.

This post is not here to convince you.

This post is here to give you some clues, a few glimpses of sparkling stars on the firmament that is your interface to the underlying reality.

Here, from the cluster of concepts that make Lisp an amazing, joyful superpower:

Joy is power is getting shit done

Stretching

Why do I do 90 seconds burpees in the morning on most days?

I do this to touch my heart rate max and this has a reason.

By stretching the system to edges,

it becomes more flexible,

just quote( huberman)

Taste

How to use 100% of your brain.

I think this was like 10 years ago that people walked around claiming that we only use 5% of our brains or some garbage like this.

I guess all kinds of people have fun making claims about how the brain works. And because the brain is super intriguing by itself anything that has a brain in its explanation sounds like some intriguing insightful thing.

Either way, here are some ideas about taste and sensibilities:

Some ways of knowing are intuitive. How do we know what is good and what is bad? What is good design, and what is bad design?

Some of this is processed in the realm of feeling. Also called sensibilities, also called system 1, also called intuitions.

When a master is crafting a piece, they are using their sense of aesthetics and their taste, to judge and make decisions.

How could it be otherwise? For if they would not use the feeling part of their mind, they would not use their whole mind. And how could you achieve mastery without using the whole mind?4

Taste is an interface into the rest of our mind.

If you only used mainstream programming languages so far, you do not know yet what it means for a language to be beautiful.

If you don't know Lisp (or its variant, Scheme), you don't know what it means for a programming language to be powerful and elegant.

So you do not know yet that taste matters in knowing the power difference in programming languages.

This is why now I talk about taste in another realm that you already know about. Art, stories and explanations.

What makes people say this is the most powerful language?

What makes one story better than another story? What makes one thinker's explanations better than another thinker's?

The answer is it fits your tastes. The answer is you think this is interesting and then there is more of that interesting stuff. The answer is it harmonizes with your mind in some way.

When I read a great story I sometimes think now there could be more of this stuff and then there is more of this stuff.5

With the greatest art, it can feel like that the artist was exploring the same space of ideas that I would explore. To the point where it is as if as a consumer of the art I am exploring parts of my psyche. Like landscapes that were already there, only to be wandered systematically. In reality, the artist was expressing something they find intriguing themselves. And either by overlap, by alikeness of mind or by them intuiting what I would like to experience, they created these substances to explore for me.

The best books do this with the story: I wish more of this would happen. I wish we would read a bit more of Harry's wizard classes.

The best video games do this with world, concepts and game mechanics.

I want to be as powerful as those mages. And then it delivers on making you powerful, as if by growing as a character.6

I want to see more of the magic system, different kinds of magic, powerful magic.7

Taste can express itself as a joyful, harmonious intrigue. Or as the feeling of gaining a deeper understanding of the world, or gaining more powerful ways to think and do things.

There is something deeply intimate in sharing what this innermost mischievous, childish aspect of our minds is up to. Maybe this is me being German but it feels like something to be ashamed of.

To explore one's taste is to acknowledge the kinds of things that one inner mischievous, childish, curious mind is intrigued by.

It is not easy to explain what makes the best stories and books. Usually, we say this is a great book. And we mean that a person's taste is extraordinarily powerfully intriguing. The qualities that make this intrigue are extremely hard to explain. A masterful piece of art is by definition the

What makes one programming language better than another programming language?

Well, what makes Harry Potter And The Methods Of Rationality a superbly sick book? What makes The Witcher 3 a superbly sick game? What makes The Pirates Of The Caribbean and The Man From The Earth superbly sick movies? What makes Emacs a superbly sick text editor?

The answer is that if you have good taste, you will know.

And this might not be easy to explain, the shortest possible explanation would be for the other person to experience what you have experienced.

Sometimes there is a hint of power or more ideas of the same stuff or of landscapes to explore and the art/book/story is delivering.

In the next sections, I explain what I think programming languages are for. In other words, what are the activities where it matters if you have one language or another?

The reason why Lisp is powerful, elegant and intriguing is not as profane as syntax. It is not the syntax, not the names of things, not the data structures, and not anything about the form at all. Lisp is together out there with you, thinking and building your program.

The non explainable

But you will only know by experiencing it.

The answer is it fits your tastes. The answer is sometimes it does what you expect.

Taste is private in a way

A programming language is a way to express yourself to the computer.

This is the flavor of intrigue and joy that Lisp provides me.

Lisp provides a honed experience of interacting with the computer. It is

It was created by hackers and is traditionally endorsed by hackers.8

Here is one attempt at conveying one reason at the hard of the cluster of reasons.

This is not here to convince you but to

What are programming languages for?

  • being lazy
  • if you have to do less, you have the better language
  • a programming language will have to be jugdet by what it does to your mind
  • because the its purpose is to give your mind the capacity to express yourself to the computer

The mainstream is wrong about things all the time

What is programming about?

Programming is about ideas. It is about organizing, understanding, communicating imaginary entities of knowledge that explains both problems and solutions.

A programming language is a tool to express these ideas to the computer9, so that the ideas have an desired effect on computer process.

How hard is it to express myself to the computer? How close are my ideas and the resulting computer process? What is the process (me using the language), that makes the computer understand my ideas?

Language is merely a tool to make 1 affect the other. The hypothetical best language is one where there is an infinitely small barrier between my ideas and the computer process.

The hustle of the programmer is in the realm of ideas. They manipulate, create and transform the web of ideas.

Only as an annoying, grindy sub task do they need to write code in order to express these transformations of ideas to the computer. Hopefully, with a minimal loss of accuracy.

This includes thinking of counterfactuals, and thinking to make experiments. To see, if the system was this way, would the bug be there?.

Hints of good design in Clojure

The magic

Experiments

Every programmer knows

Since you cannot know what you don't know

Being Alien

Not every change is an improvement, but every improvement is a change.

If there really is a language this much better

Clojure is generally said to bring back the fun in programming. 10

It is commonly suggested to young programmers to learn Lisp in order to expand their mind.11. Consider the Perlis quote

A language that doesn't affect the way you think about programming, is not worth knowing.

There are a few reasons why

Footnotes:

2

For instance Stallman:

The most powerful programming language is Lisp. If you don't know Lisp (or its variant, Scheme), you don't know what it means for a programming language to be powerful and elegant. Once you learn Lisp, you will see what is lacking in most other languages.

4

At least this is on the whole how I think it works for human masters of a craft.

I don't think the strong form of the claim is a logical necessity. I.e. I do not believe that it is logically necessary for an intelligent system to use most of its mind

5

The last few books I had this with where Neal Stephenson. All those are now some of my favority books:

  • Anathem
  • Snowcrash
  • The Diamond Age
  • Seveneves
6

That is Gothic 2.

7

That is Avatar: The Last Airbender and the magic is called bending.

8

See Paul Graham for this trail of inquiry.

Stallman

The most powerful programming language is Lisp. If you don't know Lisp (or its variant, Scheme), you don't know what it means for a programming language to be powerful and elegant. Once you learn Lisp, you will see what is lacking in most other languages.

9

And to programmers.

10

I think Stuart Halloway has that in a youtube talk.

11

LISP is worth learning for a different reason — the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot. (You can get some beginning experience with LISP fairly easily by writing and modifying editing modes for the Emacs text editor, or Script-Fu plugins for the GIMP.)

Date: 2023-06-25 Sun 20:12

About
Contact
]]>
https://faster-than-light-memes.xyz/bb-tasks-and-more.html bb-tasks-and-more 2023-06-20T23:59:59+00:00 bb-tasks-and-more

ftlm

bb-tasks-and-more

Design is about pulling things apart.

Rich Hickey

With bash-completion we get a really nice boost for making shell commands from Emacs. Babashka tasks completions are for free, together with make, same as dynamic git, ssh and whatever.

Here is the screencast on youtube.

Below are sort of show notes.

1. Make sure you have completions in your shell (bash for me)

  shell-file-name
;  (setf shell-file-name "/bin/bash")

1.a for bb:

https://book.babashka.org/#_terminal_tab_completion

.bashrc

  _bb_complete() {
    BB_TASKS=$(bb tasks|bb -io '(->> *input* (drop 2) (map #(-> % (str/split #" ") first)))')
    BB_HELP=$(bb help|bb -io '(->> *input* (map #(->> % (re-find #"^  ([-a-z]+)") second)) (filter some?))')
    COMPREPLY=($(compgen -W "$BB_TASKS $BB_HELP" -- "${COMP_WORDS[$COMP_CWORD]}"))
}

complete -f -F _bb_complete bb

2. Setup bash-completion

https://github.com/szermatt/emacs-bash-completion

(use-package bash-completion
  :config
  (bash-completion-setup)
  (setf bash-completion-use-separate-processes t)
  (defun bash-completion-capf-1 (bol)
    (bash-completion-dynamic-complete-nocomint (funcall bol) (point) t))
  (defun bash-completion-capf ()
    (bash-completion-capf-1 #'point-at-bol))
  (add-hook
   'sh-mode-hook
   (defun mm/add-bash-completion ()
     (add-hook 'completion-at-point-functions #'bash-completion-capf nil t))))

read-shell-command

Afterwards, this should work for you: (I always try with git check...).

(read-shell-command "your command: ")

read-shell-command sets up a special keymap where tab now means completion-at-point.

read-from-minibuffer, 3thr arg

(read-from-minibuffer
"foo: "
nil
(let ((m (make-sparse-keymap)))
  (define-key m "f"
              (defun my-hi ()
                (interactive)
                (insert "lol")))
  m))

Commands that use read-shell-command

  • async-shell-command, shell-command
  • dired-do-async-shell-command, dired-do-shell-command
  • compile

I use project.el to run async shell commands and compile in the project root.

Run in any dir?

Design is about splitting things apart.

  1. Select a current dir, up to you. My main paths would be
    • consult-dir,
    • project-switch-project,
    • consult-buffer + bookmarks
  2. Run async-shell-command or a friend of it.

More config

  (setq async-shell-command-buffer 'new-buffer)

  (defun path-slug (dir)
    "Returns the initials of `dir`s path,
with the last part appended fully

Example:

(path-slug \"/foo/bar/hello\")
=> \"f/b/hello\" "
    (let* ((path (replace-regexp-in-string "\\." "" dir))
           (path (split-string path "/" t))
           (path-s (mapconcat
                    (lambda (it)
                      (cl-subseq it 0 1))
                    (nbutlast (copy-sequence path) 1)
                    "/"))
           (path-s (concat
                    path-s
                    "/"
                    (car (last path)))))
      path-s))

  (defun mm/put-command-in-async-buff-name (f &rest args)
    (let* ((path-s (if default-directory (path-slug default-directory) ""))
           (command (car args))
           (buffname (concat path-s " " command))
           (shell-command-buffer-name-async
            (format
             "*async-shell-command %s*"
             (string-trim
              (substring buffname 0 (min (length buffname) 50))))))
      (apply f args)))

  (advice-add 'shell-command :around #'mm/put-command-in-async-buff-name)

  (add-hook 'comint-mode-hook
            (defun mm/do-hack-dir-locals (&rest _)
              (hack-dir-local-variables-non-file-buffer)))

  ;; it logs a warning when you hack a local
  ;; Making process-environment buffer-local while locally let-bound!
  ;; It is sort of want I want though
  (advice-add #'start-process-shell-command :before #'mm/do-hack-dir-locals)

  (advice-add 'compile :filter-args
              (defun mm/always-use-comint-for-compile (args) `(,(car args) t)))

shell

(defun mm/with-current-window-buffer (f &rest args)
  (with-current-buffer
      (window-buffer (car (window-list)))
    (apply f args)))

(defun mm/shell-via-async-shell-command ()
  (let ((display-buffer-alist
         '((".*" display-buffer-same-window))))
    (async-shell-command shell-file-name)))

(advice-add #'mm/shell-via-async-shell-command :around #'mm/with-current-window-buffer)

(setf shell-kill-buffer-on-exit t)

(add-hook
 'shell-mode-hook
 (defun mm/shell-dont-mess-with-scroll-conservatively ()
   (setq-local scroll-conservatively 0)))

I invoke mm/shell-via-async-shell-command with a stumpwm keybinding. This is the only reason I need mm/with-current-window-buffer irrc.

See also

Date: 2023-06-20 Tue 20:27

About
Contact
]]>
https://faster-than-light-memes.xyz/contact.html Contact 2023-03-01T23:59:59+00:00 Contact

ftlm

Contact

Contact me at

Benjamin.Schwerdtner@gmail.com

Or poke me @Benjamin.Schwerdtner on the Clojurian slack.

Date: 2023-03-01 Wed 12:38

About
Contact
]]>
https://faster-than-light-memes.xyz/dir-env-process-environment.html dir-env-process-environment 2022-10-17T23:59:59+00:00 dir-env-process-environment

ftlm

dir-env-process-environment

Introduction

Making shell commands is one of the great joys of emacs.

An advanced use case is that you want to set up a process environment for everything you do inside some project.

What I show here works for compile, shell-command, and even cider connections.

The setup

.dir-locals.el:

((nil
  .
  ((eval progn
         (make-local-variable 'process-environment)
         (setq process-environment
               (copy-sequence process-environment))
         (setenv "FOO" "hurr")))))

Yes, it is a bit convoluted but for a reason. We need to copy the list, else if somebody modifies the cdr locally, that would modify the global value. (In the case that FOO is an element in the list somewhere already).

The answer mentions setq-local. I tried that without success.

Shell-command and friends will inherit the process environmen. It pretty much just works.

From the project I currently work on:

((nil
  .
  ((eval progn
         (make-local-variable 'process-environment)
         (setq process-environment
               (copy-sequence process-environment))
         (setenv "AWS_PROFILE" "datalake-deployer")
         (setq-local cider-clojure-cli-aliases (concat cider-clojure-cli-aliases ":dev"))))))

Now I start cider connections with AWS_PROFILE set correctly. Also I have a babashka task for deploying that needs this env and it all just works.

Non-file-buffer

By default, .dir-locals.el does not apply to buffers without file names. (When the local variable buffer-file-name is not set).

There is a function hack-dir-local-variables-non-file-buffer for this purpose. This is called by dired, also magit.

I usually start processes from either a (source) file buffer or dired.

revert with grace

When you make a change to your .dir-locals, call revert-buffer in whatever buffer you want to have the effect. It hacks the local variables again for the buffer.

Date: 2022-10-17 Mon 09:56

About
Contact
]]>
https://faster-than-light-memes.xyz/memetics.html Memetics 2023-05-18T23:59:59+00:00 Memetics

ftlm

Memetics

(This is a work-in-progress page).

See Biological Notes on The Vehicles for my current musings on meme-engine algorithms for cognition.

Go read The Selfish Gene if you have not done so yet.

Seriously, do it.

It is not accidental that I call this blog faster than light memes.

The concept of the meme has intrigued me and many others.

The Selfish Gene is a book that introduces a perspective, Genes Eye View of Evolution (Dawkins 1976). Introducing perspective might be the most powerful kind of knowledge.

With a happy little conceptual jump, Dawkins applies the perspective to mental content and discovers the memes.

Notable works on memetics:

The Beginning of Infinity, David Deutch

Deutsch fleshes out the existence of 2 classes of memes that he calls rational and non-rational.

A fascinating read, with a red thread through scientific inquiry, why flowers are beautiful, ethical truths, the nature of the universe and the fate of civilization. Big history.

The Meme Machine, Susan Blackmore

Blackmore lays out some memetic concepts, Copy-the-product, Copy-the-instructions,

introduces the term Memeplex (Wikipedia), a term that comes from genetics geneplex. In memetics, we can play the game of reasoning by analogy to genes.

Blackmore goes on to describe a meme's eye view of how culture and the brain evolved. And makes hypotheses about how music, language and other aspects of cognition, especially social cognition might be explained by memetic processes.

Also big on how memes might become the driver of genetic evolution.

Daniel Dennett's recent work

For instance, From Bacteria to Back and Back.

Dennett is an exceptionally clear thinker. He shows how memetics fits as a nice model for how religions work.

He is pointing out the power of good ideas, the most powerful ones he calls intuition pumps.

He makes the analogy of computer virtual machines to how minds work. Meaning that on some level of the hierarchy, the underlying working of the mind are abstracted away enough so any idea fits on any brain, the same way the Java Virtual Machine abstracts about different operating systems.

download memetic applets to your neck top.

This idea ties into Blackmores Meme Machine, where she hypothesizes that the genetics that makes brains suitable for memes where selected for.

An evolutionary driver for making brains that have the infrastructure of having ideas, without specifying the contents of the ideas.

Naively, content is the memes like software is to hardware.

One thing I think Dennett gets wrong is that much of his theorizing is about person-jumping memes.

I think it is important to notice that memes can reproduce and live within a single mind and I always felt like Dennett was ignoring this idea for some reason.

The strongest example I can come up with is a personal rumination or some such. This is a memeplex that might never be replicated in another mind but reproduces itself again and again within one mind.

But of course, once you think of it this way, then maybe much of the machinery of the mind is assembled, in part, darwinistically.

Why this blog is called Faster Than Light Memes

Replicating information, and ideas are the real deal of what the universe is about.

The difference between humans and other animals is our ideas. Humanity is the memes, more than it is about the biological substrate carrying them.

It is the memes that allow us to go to the moon - In spite of our biology, not thanks to our biology.

David Deutsch has recently described his philosophy nicely on the Tim Ferriss Show.

As civilizations become more advanced, it is knowledge and ideas that are the driving force behind what happens in the universe.

Consider a meteor flying towards Earth. Newtonian physics predicts an impact. But because of civilization, it might be deflected.

Eventually, ideas will have the power to create, transform and destroy stars and galaxies.

Dawkins mentions the memes are currently still clumsily floating around in their primordial soup.

Once we start doing things like converting all reachable matter into computronium1, it will be the descendants of our ideas that will shape the universe.

If we should find ways to go faster than light, the memes will spread faster than light through the universe.

The title of my blog is just a hopeful wish, that the axiological potential of humanity is greater by a factor of x because if you go faster than light you can reach more of the universe.

Of course, we, the memes, might figure out something more useful than populating the universe. Like making ourselves smaller and smaller or something.

Faster Than Light is just a phrase underlining the idea of potentially spreading in the universe.

Going faster than light or even spreading in the universe is not necessarily a goal - maximizing human flourishing is.

Footnotes:

1

A hypothetical optimal configuration of matter for doing computation.

Date: 2023-05-18 Thu 18:57

About
Contact
]]>
https://faster-than-light-memes.xyz/mid-term-goals.html Mid-Term Goals 2022-11-17T23:59:59+00:00 Mid-Term Goals

ftlm

Mid-Term Goals

This is inspired by Hilbert's problems list.

This is a list of my current goals for moving humanity forward.

Some of these are easier than others. Being effective means finding the easy things that have leverage.

hgAYzqu.jpg

Figure 1: Solarpunk city with clear skies. Utopian high-tech future. Open spaces and trees. Flying buildings. Water.

Thinking big and what I think life is about

Why not think big? It's better than thinking small as far as I can see.

We are already influencing the long-term trajectory of civilization, regardless of whether we acknowledge it or not.

I say civilization is life. We currently have sciences that are largely defined by their methodologies and institutions with a different science for say organisms, computers and technology. You might then think that life is what biology studies, but it is not so true. Life is also ideas, artifacts, civilization and computers.

Life is the craziest thing in the universe and it just starting. And we have the opportunity to shape the next stage of life, civilization, and intelligence.

There are a few things that fall out of common sense in my opinion, invariants: Suffering and death are bad. Life is good. Progress is good because it allows for more life, creativity, beauty, harmony and joy.

  1. This was true in the distant past. It was true when we were Cambrian fish.
  2. What is true across the eons is likely to stay true in the coming eons.
  3. You really cannot know what amount of beauty and joy lies on the other side of progress. Nobody was foreseeing Bach or The Witcher 3 when the first primates started living in trees.

Mid-term I want to work on a solarpunk utopian future, biasing the outcomes towards human flourishing and ushering in the singularity1 quicker.

This is a future with many trees and clear skies. In cities full of innovative and harmonious people, gazing at the stars and building great things.

Techno Optimism

What is techno-optimism, chat gpt?

Techno-optimism is a worldview or attitude that technology can bring about positive outcomes and solving some of the world's most pressing problems. It is the belief that advances in technology will ultimately lead to a better world, and that technological progress will help humanity overcome many of its current challenges, such as poverty, disease, and environmental degradation.

Techno-optimists tend to be enthusiastic about emerging technologies, such as artificial intelligence, biotechnology, and renewable energy, and they see these technologies as powerful tools for solving social, economic, and environmental problems. They often believe that technology can enable greater productivity, efficiency, and innovation, and that it can ultimately lead to a more prosperous and sustainable society.

However, techno-optimism is not without its critics. Some argue that it can lead to an overreliance on technology and overlooking important social and ethical issues associated with technological progress. Others point out that technology can exacerbate existing inequalities and that it can also have unintended consequences that are difficult to anticipate.

chat gpt end

Those critics are not seeing the full picture. Maybe civilization optimism would be the better word anyway. Science, reason, and humanism are all part of the story.

The point is to understand how and why civilization and technology are useful for bringing about human flourishing and well-being. And to continue the already made advances. And to realize, historically, how precious our current situation is.

For the inequality thing. This is not at all how mobile phones, the internet and medical advances (penicillin anybody?) turn out to work. By the time technology works well and is cheap to make we can make it available to all humans. Humanism and progress give us the ethical framework to have equal opportunity etc. as a goal.

1. Solve Poverty

Why?

  • Obvious low-hanging fruit.
  • Enable huge productivity gains by allowing large populations to contribute to science, engineering, medical research etc.

How?

  • Make a lot of money and push projects.
  • UBI
  • Democratize2 goods
  • Democratize education
  • Democratize opportunities
  • Lower the costs of production for material + infrastructure, food and energy.

How do we know we make progress?

  • See Our world in data.
  • I have been working in this space for 5 years now and my current hope is to fix extreme poverty around 2030. (Which is a few years earlier than current projections last time I checked).

2. Solve longevity

  • Fix aging
  • Fix other diseases

This means you get an indefinite biological substrate lifespan. This might be rather low-hanging fruit, see Livespan with Dr. David Sinclair. Consider that fixing aging fixes a lot of diseases at the same time. Being biologically young means you fend off diseases.

Also, the same kind of advances fixes autoimmune diseases, Alzheimer, and cancer. See also the work of Aubrey de Grey for intelligent reasoning on this.

How do we know we make progress?

  • When you know your biological age the same way you know your weight.
  • When a head of state pronounces Not a minute longer dying from old age.

3. Solve energy

Why?

  • Energy consumption is linked to affluence.
  • Unlimited or virtually unlimited energy unlocks insane infrastructure and productivity perks
  • Be able to pull CO2 from the air3.
  • Water treatment plants etc4.
  • You only need enough energy so there is always some there the moment you look.
  • Kardashev Scale. The advancement of the civ.

How?

  • Industrial scale fusion, a SpaceX for fusion Lex Friedman + Dennis Whyte.
  • A green manhattan project (Yuval Noah Harari has mentionend this).
  • Fission? 5
  • Per definition, renewables, since we play a long game.
  • When it comes to getting rid of gas and coal you have to acknowledge keeping civilization running is a goal.

How do we know we make progress?

  • When we put industrial viable fusion energy on the grid.
  • When you pay a flat rate for your electricity bill.
  • When electricity is provided as a public good, in affluent countries.

4. Fix software (Rant)

Seriously, most web and mobile software only works so-so nowadays because of bloated software. Everything is bigger and more complicated than it needs to be. Reloading some app because it stops working is the norm. This garbage is not acceptable in my vision of the future.

Software is supposed to be focused, effective and competent.

The price we pay right now for bloated and uninspired software is insanely high. How many mental energy hours go into reloading some app that stops responding6? Seriously, this is a global humanitarian issue.

Another issue is something I call mind-suck software now. This is software that is highly designed and explicitly or implicitly informed by behavioral psychology. To draw our attention and suck our time. When I click on an app with a blue icon because it has a red dot in the corner, that is not merely my fault, not only my lack of self restrain. That is also the fault of the people that made this software in the first place. This is an ethical issue. Long term I hope we understand which kind of software is conducive to our well-being and which is sucking our minds. 7 Mind-suck software belongs in the trashbin of history.

Existing software that lets me feel the competence of the computer is Unix/Linux, FOSS tools, Git, Emacs, and non-bloated parts of the web like Wikipedia. We can do it right.

The phone is a completely opaque object to me, with virtually no power to reach into it and make it do what I want it to do. Instead, I need to hope app vendors come up with something I find useful.

One of my fears currently is that BCIs will inherit from the current mobile model of software delivery. I think this would delay the singularity by multiple years.

The issues are uninspired practices and a disregard for the wisdom of the early days of computing. Also, the focus on financial incentives breeds less ambitious projects.8

Also, if it is FOSS, it tends to become small and focused, if it is proprietory, it tends to become large and bloated.

All user interfaces could be more like Data Rabbit right now. Think of the difference in productivity across the whole world. People would not fight computers anymore but wield great tools of thinking.

How?

  • FOSS
  • Reinvent the heyday of Lisp and Smalltalk interactive systems. These were made by people for people that build systems.
  • Ideas from Bret Victor, Rich Hickey, Jack Rusher and others.
  • It will be easier when we have more abundance and the incentives don't need to be primarily financial anymore.
  • I choose Clojure. The community has an emphasis on thoughtfulness about how to make good software. It is a Lisp with a focus on interactivity, and raw power through succinctness. Great polymorphism constructs. A strong concurrency model and reach by being hosted on JVM and javascript. In short: A language for humans by humans for building effective information systems.

How do we know we make progress?

  • When you can change what a button does on your phone.
  • When syncing data between 2 programs on mobile is not an advanced operation.

5. Higher tech

For obvious reasons, any of those can help fix things on this list:

  • AI, information technology, automation.
  • Better computer interfaces (conversational, … ).
  • Nanotech, material science.
  • Biotech, BCIs, genetics.
  • A science and engineering of processes, policy and government 9.
  • Also infrastructure, networks10, internet connection, water and goods.

How do we know we make progress?

  • When a computer asks you back about an edge case you have not thought about while explaining your task to it.
  • When you don't buy toothbrushes at the store anymore because you have a matter compiler or printer or nano factory.

The special effectiveness of AI

Say intelligence is the ability to achieve complex goals. If we have that in computers the same way we have chess computers, it is an instant global win condition. A general AI could solve the things on this list, including making better AI. Which would further increase its capability of fixing the things on this list.

6. Solve food

  • Cheap, tasty, clean meat.
  • Just higher-tech food production.
  • Plants. Better plants. More effective plants. And plant-growing buildings.

7. Preserve biodervisity and ecosystems

Why?

  • Organismic life has an intrinsic value to it.
  • In a medium-long-term situation where energy, material and compute are abundant, maybe 11, the information you get from gene sequences and analyzing ecosystems are the most valuable thing there is.

How?

  • Relatively hard.
  • Fixed by 3, 8 and 9, which you in turn push best forward by increasing affluence.

How do we know we make progress?

  • When the extinction of any species is a global tragedy.

8. Solve government and policy

Why is governmenting not more like engineering? Anyway, it is an unsolved problem for obvious reasons:

  • lack of UBI, poverty
  • lack of decisive climate safety action
  • lack of world peace
  • noise pollution
  • users citizens need to bother with paperwork, tax stuff is not automated.

How?

I don't know what to do mid-term except try to push affluence globally. Higher affluence correlates with a more reasoned government generally (See the Nordics). This way I would generally bias for more desirable outcomes.

Outcomes

The moment we have super-intelligent AI, we get one of multiple possible outcomes, with either a group of people controlling an AI making the decisions or an AI making the decisions. If you are skeptical about this statement, try to play a party of chess against a chess computer12.

How do we know we make progress?

  • Everybody's education level goes as high as possible. I believe that means everybody can achieve a Ph.D.-level education at minimum.
  • UBI.
  • Explicit policies against noise pollution 13.

9. Develop more far-sighted incentives14

Why?

Companies are arguably the most competent actors in the world right now.

The fact that Starlink is the entity that fixes the internet in Ukraine right now and not a government is showcasing this for me.

What does not fit in my solarpunk future yet is that companies are currently maximizing money, instead of human flourishing.

How?

In the mid-term, by pushing forward easier things on this list. Bring about abundance and rational decision-making.

Another idea is to make tons of money and become a powerful corporate entity yourself. (This counts for anything on this list).

Create enough abundance so money is not the driver anymore. This is called Post Scarcity and I think reality looks like this would work. Aka more affluence leads to more attention on human flourishing.

How to know if we made progress?

  • Corporate entities are explicitly pushing to solve other issues on this list.
  • A corporate entity fixes infrastructure in a region of war (Oh, we are making progress!)

10. Solve immortality

For starters something like mind-uploading. Where you have a mind backup inside a fault-tolerant system.

Medium-long-term we need to make sure earth is safe from meteors and gamma rays. Goes into super long-term. By becoming a civilization after the stars are gone, and surviving the death of the universe, a civ might ultimately decide the fate of the universe.

How to know if we make progress?

  • When the death of a single person is a global tragedy.
  • When you don't tell children about the history of death until they are old enough to stand it.
  • When Misery was

Reading

  • The Singularity is Near Ray Kurzweil It is a truly seminal book. It makes you appreciate exponential processes and then it maps that to computers and biotechnology. Making you see the logic of how fast technology is growing crazy powerful and tiny.
  • Yuval Noah Harari, together with Pinker and others an eminent thinker and proponent of civilization optimism.
  • Steven Pinker Enlightenment: Now The Case for Reason, Science, Humanism, and Progress
  • Jared Diamond Guns, Germs, and Steel. An eye-opening book about large-scale, big-picture thinking. How civilizations form. Science fiction without being science fiction. It tells you everything could be different.
  • David Deutsch The Beginning of Infinity: Explanations That Transform the World Big history, big ideas. Connects scientific inquiry with how evolution works. Explains the power of good ideas, talks about beauty, ethics, the fate of the universe and all that with a red thread going through it. Perspective-creating. A continuation of The Selfish Gene in some ways.
  • Engines of Creation: The Coming Era of Nanotechnology K. Eric Drexler. Drexler calmly and matter-of-factly explains how you can have a machine the size of a garage printing a car. The only thing needed is some advances in material science, no new physics is required.
  • If you enjoy thinking about possible outcomes regarding AI, Max Tegmark, Life 3.0/. If you read nothing else from the book, the first chapter describing the fictional near-future secret group called the /Omegas is extremely thought-provoking. This is the idea of a small group of individuals controlling a super-intelligent AI, taking over the world and biasing for human flourishing.
  • Superintelligence: Science or Fiction? | Elon Musk & Other Great Minds
  • I don't fully know why but Richard Dawkins The Selfish Gene is more than an just eye-opener about how evolution works it is also an eye-opener about the power of thinking and common sense.
  • David Sinclair on fixing aging https://www.lifespanpodcast.com/
  • Aubrey de Grey, very vocal about how we need to overcome deathism, the idea that death is something to accept.
  • Eliezer Yudkowsky has written about the ethics of progress, longevity and more. If anything in this post resonates with you and you have not read Harry Potter And The Methods of Rationality yet, seriously, I can advise doing that. I am not alone in saying this. The book covers topics on morality, fixing death, being a scientist, and the navigation problem of fixing the world.
  • Isaac Assimovs The Last Question is somehow a good meme about the big-picture.

Footnotes:

1

In terms of Ray Kurzweil. Techno utopian high tech outcomes that change the game completely.

2

With Democratize I mean make it available to everybody, without conditions. And as cheap as possible.

3

I have picked up this factoid from a Helion Energy blog post somewhere.

4

Chat gpt mentioned this when I asked what the perks of unlimited energy would be

6

I am not even thinking about windows users that are rebooting their PC. I can handle only so much brokenness in my mind right now.

7

Sam Harris has thought publically about this on multiple occasions: The price of distraction, Why I left Twitter

8

Alan Kay has talked about the dynamics of innovation and how you don't get this in the climate of short-sighted monetary goals

9

Already exists, of course, I am just too ignorant to even list the correct names.

10

I really enjoyed this talk by Dylan Beattie it kind of went to different concepts about networks and supply chains etc. He also mentioned Diamond Age style nanotech that would change the game of supply chains completely. He pointed out there might be a new logic to supply that would entail information and experiences, not goods.

11

I see multiple possible worlds in this regard. Depending on

  • A. How hard it is to fabricate evolutionary organismic wisdom.
  • B. How valuable evolutionary organismic wisdom is.

We could make some back-on-the-envelope reasoning about A, but B is completely unknown. We don't know the value of biodiversity and ecosystems yet and we should treat them as extremely valuable.

Also aesthetically, a solarpunk utopian civilization would value organismic life just for its intrinsic value.

12

That is from Max Tegmark, Life 3.0.

13

I am just taking noise pollution as an example where human well-being is not at the center of what we are doing with civilization yet.

The day we ban foliage blowers is the day we can rejoice, for we are on the way into our solarpunk utopia.

14

This idea is straight from Alan Kay. In one of his many appearances on youtube and podcasts.

Date: 2022-11-17 Thu 20:11

About
Contact
]]>
https://faster-than-light-memes.xyz/not-even-the-sky-is-the-limit.html not-even-the-sky-is-the-limit 2022-11-15T23:59:59+00:00 not-even-the-sky-is-the-limit

ftlm

not-even-the-sky-is-the-limit

Cold showers are a hello world for being determined.

Introduction

I have been practicing Wim Hof Method for years. It is a spiritual path of sorts.

There is this thing where you embrace being an animal, and animals are really hardcore man. Human animals plan, think and discover how to world works. The brain is the control hub of our inner physiology also. Getting in touch with your physiology is not mystical, and not reserved for a certain kind of person either. It is using the paths in your brain that evolved to do just that. 1

To close the loop: The inner physiology is another part of the world. With its mechanics, story and places that can be discovered - and mastered to various degrees. Such is the human way, you are the animal

  • uses thought
  • likes stories
  • makes sense of objects etc in the world

Where can you start? With the things you already have control over. Hence breathing techniques, stretching and cold exposure. Emphasize the in-breath over the out-breath and you are pumping adrenaline. The other way around and you get more relaxed. Cold exposure pumps dopamine, with a long arc. 2 It makes the whole day awesome. A cold shower is already an achievement that sets you up for performance. Wim has mentioned somewhere on the free part of his app something about self-determination and having "the cold as a teacher". An upsight clicked clicked in me that will try to share here.

One way to learn is to learn on a playground

There is a reason we make hello world programs. We learn in the small what is similar for the large.

Say Wim Hof is right and self-determination is a mental thing I can grab How do I learn to do so? Also importantly, how do you even know you are doing it? Enter cold showers ("The cold is our teacher"). It is hard to kill yourself with a cold shower, yet it takes mental energy to go into one and to stay. It gives you a chance to be determined in a small, controlled, safe environment. You manage to endure a wall of physical discomfort, you are doing it. This is what determination is.

just do it

In the lore of Wim-hoffing, you keep a calm mind and observe yourself being able to do it.

You are deploying the mental capacities that you might call determination.

The cold shower is the playground that allows you to see how it is to be determined. You observe the mentality, the mechanics, the feel, the drive, the just doing it. What you are when you are being determined. This then, shows you how to be determined elsewhere. The cold is not an end goal, it is a simple, easy playground where we can test how it is to be determined. This also means we have a benchmark for whether we are deploying determination, or not.

To learn something you need some way of telling whether you are doing it right.

I connect this to an experience I had while I was learning to juggle. There was a moment when I was doing 1 or 2 balls when I realized: here is a limit, a place where I can invest in training and I will get better and build a foundation and eventually be able to juggle. (I was right).

The only place where you can grow is at the edge.

Huberman

Professor Huberman is since recently one of the great science communicators of our time. About physiology, neuroscience and (my words) frankly, the human soul.

Transcript from a recent Q&A event (you can find it on the Huberman lab podcast feed):

If you want to get the most out of the cold exposure then you want to get to that point of "I want to get out of here, but I know I can stay in safely, but I really want to get out of here".

It's a little hard to explain, but there is just so much learning in those short moments about where your mind goes. And this sounds subjective and maybe a little whishy-washy. You can realize great things about yourself in those moments. You can find insight in those moments.

I agree. I call this learning how to be determined.

The practice

I can recommend the Wim hof app to get started. There is a diary thing where you start with 10-second cold showers after a warm shower etc.

Tip: if you have a dispatchable shower head, put it in your hand and move it around. Cold exposure is all about control. If you have the shower head in your hand, you gain control.

Footnotes:

1

One way to describe this is by having a set of inside jokes with the physiology driving parts of your brain. Using your own style.

2

Andrew Huberman has in recent times communicated beautifully about the the current science of cold exposure, breathing technique and stretching.

Date: 2022-11-15 Tue 19:20

About
Contact
]]>
https://faster-than-light-memes.xyz/pearls-of-introspection.html pearls-of-introspection 2022-11-12T23:59:59+00:00 pearls-of-introspection

ftlm

pearls-of-introspection

Recently, I watched BugsWriter falling in love with elisp 1 - he said about describe-mode

Why did nobody ever tell me about this?

This post is called Pearls of introspection.

All of Emacs is one bright pearl.

The describes

describe-mode

Lists all current keybinds in a buffer. Huge output, sometimes what you want.

describe-char

Emacs is a text editor, text is made up of chars. describe-char is useful if you want to know what face is rendering. It goes beyond that by showing string properties, overlays, and buttons. This can be useful for debugging.

Story: Once I deleted some packages on my system, then I go into emacs info and some of the text is not rendered right.

describe-char gave me the hint, the fixed-pitch face wanted "Monospace Serif" or some such but I only had Monospace.

So I did this and was happy ever after:

(set-face-attribute 'fixed-pitch nil  :family "Monospace")
(set-face-attribute 'fixed-pitch-serif nil  :family "Monospace")

Worth binding:

(define-key help-map (kbd "c") #'describe-char)

describe-key

"What does this key do?" - the answer is describe-key and hit the key.

describe-function

Emacs functions have amazing docstrings.

The help buffer has a keymap of its own, try ? to list keybinds.

Highlight: s to go to source.

describe-keymap

Probably faster than describe-mode, renders a keymap in a help buffer. Try describe-keymap -> help-map hehe.

prefix-help-command

You type ? after starting to type a prefix, then you get the binds.

embark-bindings

An alternative to the default ?, it is amazing. I get a vertico completing-read of the binds.

M-x describe-

There are more, some of them I never used. Emacs is vast like the ocean.

view-lossage

You accidentally hit some key, and something unexpected happens. view-lossage is your friend. It shows the last keys + commands.

It is like the morning-after pill version of describe-key.

story: I sometimes accidentally hit y before typing the text for an avy command.

Every time I was like "Holy cow whatever I hit there is powerful". 2

I didn't know about view-lossage. The thing is, it would not have helped, because avy is reading the key, then dispatching on the key. I guess it needs to go through the keymap system or something to show up in view-lossage.

apropos-value

This helps me about once per year.

It is extremely satisfying when you use this and it helps you. I once figured out about revert-buffer-function by using it.

You can revert shell-command buffers to rerun the command but I did not know by which principle.

apropos-value, then typing my shell command showed me there was a buffer-local variable called revert-buffer-function. It worked because Elisp closure objects print with their environment. In other words, the value of revert-buffer-function was a lambda that printed with my shell command. It is quite wild.

find-library

Read code, and do little experiments. I am not sure but I think there might be something profound about Elisp and emacs. I think the language is the program and the program is the language or something. Knowing the program is to know the language and knowing the language is to know the program. (Insert link to top Elisp functions blog post here).

where-is

I just discovered this via describe-keymap into help-map lol. This is like describe-key but you say the command and it says the keybinding.

Footnotes:

1

I thought lisp was going to be complicated but it is simple.

That is an interesting tension between outside perception and the actual language. Since you write the AST directly, you can say what you mean. The power of lisp is that the code is made of

  1. Ideas
  2. There is nothing else.
2

It makes the cursor stay and yank the target word. Hit ? before typing the keys for avy. The way it works is that avy can dispatch with different actions, the default is to jump to the location, but y for example yanks a word and makes your cursor stay where you are. It is really powerful. Ace-window has the same paradigm.

Date: 2022-11-12 Sat 16:02

About
Contact
]]>
https://faster-than-light-memes.xyz/aws-iam-and-cloudwatch-logs-start-query.html aws-iam-and-cloudwatch-logs-start-query 2022-11-30T23:59:59+00:00 aws-iam-and-cloudwatch-logs-start-query

ftlm

aws-iam-and-cloudwatch-logs-start-query

User with accountId: 123456791011 is not authorized to perform StartQuery

Example iam policy for querying cloudwatch logs (that one works):

  {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:StartQuery",
            "Resource": "arn:aws:logs:us-east-1:123456791011:log-group:hairy-log-group-name:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:GetQueryResults",
                "logs:StopQuery"
            ],
            "Resource": "*"
        }
    ]
}

The above error you get when you try the log-group arn without the `:*` at the end.

You need the `:*` behind the log-group for some reason, probably because the log-streams also participate in the resource permission thing or something.

This was kind of hard to figure out, no examples on the official websites and you think you do it right from reading the documentation.

Date: 2022-11-30 Wed 16:29

About
Contact
]]>
https://faster-than-light-memes.xyz/bashing-is-better-than-extending.html Bashing is better than extending 2022-09-22T23:59:59+00:00 Bashing is better than extending

ftlm

Bashing is better than extending

Not how to run babashka tasks.

How bash-completion makes everything better.

How to run any shell commands.

Technology around shell-command.

Simplicity and joy.

Introduction

Ok, let's just do it. You might want to hold tight to your chair because the juiciness and elegance of what follow might just blow you over. Here is how I build my blog with babashka tasks:

bb-task-demo.gif?raw=true

Figure 1: Using compile to leverage read-shell-command and thereby bash-completions. Recompiling via revert-buffer. Dismissing the *compilation* buffer.

You might think "Ok sure, looks useful." Let me entice you with the the really impressive thing about this:

There is nothing concrete about babashka tasks nor about that specific project in my emacs config. It just works by having a bb.edn with tasks.

Made possible via the harmony between some 3 or 4 general tools. Like layers of ice. You deserve some skates to ride on it. Smoothly, gracefully and fast. Here is the story of a happy little package called bash-completion.

read-shell-command

This is like read-from-minibuffer but sets some keymap and history. Hit <tab>, you get completions from shell-dynamic-complete-functions. Those completions are sort of okay, but they do not give you command-specific completions. Invoke shell-command, then type git checkout, hit tab. Nothing happens. Yet.

bash-completion

Ok your emacs life is about to level up +1 bash-completion. Config:

(use-package bash-completion
  :init (autoload
          'bash-completion-dynamic-complete
          "bash-completion"
          "BASH completion hook")
  (add-hook
   'shell-dynamic-complete-functions
   #'bash-completion-dynamic-complete))

Here are the completions of your shell at the tips of those sweet coconut oily fingers.

Now you can do shell-command -> Hit that tab while typing git checkout .. a door just opened.

bash completions are now your lever

We have entered the realm of harnessing already existing shell completions directly.

Babashka tasks

Babashka tasks are one of the great discoveries of our time, allowing us to write build tasks in Clojure, with the development ergonomics of a lisp.

The babashka book has a section on adding shell completions. Boom. This is all you need. Now you can enjoy those babashka tasks completions.

Commands that leverage read-shell-command

They use read-shell-command. Making read-shell-command good will pay off for all these.

shell-command

Bound to M-!

This is the interactive doorway into emacs lisp start-process functionality.

Here is a nugget:

With prefix argument, insert the COMMAND's output at point.

C-u M-! date and you have a date inserted in the buffer.

Like this: Thu Sep 29 10:55:44 AM CEST 2022

Good to know:

If COMMAND ends in &, execute it asynchronously.

Output buffer

Your command output is located by default in a buffer named by shell-command-buffer-name. Or shell-command-buffer-name-async when async.

shell-command-async

Bound to M-& and has the same effect as adding a & in shell-command. To kill the process I can hit C-c C-c.

compile

Very useful, very similar to shell-command-async. Always uses the same buffer called *compilation*. You can set compile-command for instance via .dir-locals.el, then it auto makes a compile command in that project.

dired

dired-do-shell-command and dired-do-async-shell-command are symetrical with shell-command and async-shell-command. Those functions call shell-command.

Bound to ! and & in dired Docstring is worth reading. Important to know is that * expands to dired-file-name-at-point, or the marked files, but is implicit as the last arg.

shell-command-on-file

Sometimes you are currently visiting a script file and you just want to run it.

(defun mm/shell-command-on-file (command)
  "Execute COMMAND asynchronously on the current file."
  (interactive (list (read-shell-command
                      (concat "Async shell command on " (buffer-name) ": "))))
  (let ((filename (if (equal major-mode 'dired-mode)
                      default-directory
                    (buffer-file-name))))
    (async-shell-command (concat command " " filename))))

Thanks to Gavin Freeborn for the initial version of this code.

It gets even better

Let me introduce you to the wonders of revert-buffer-function. Now, revert-buffer is a powerful command by itself.

I did not know this for a while, but you can set the local variable revert-buffer-function. This pearl is in emacs 28:

(setq-local
 revert-buffer-function
 (lambda (&rest _)
   (async-shell-command command buffer)))

You say revert-buffer in a shell command buffer, to boom run the command again in the same buffer. Exactly what I want sometimes. A single key to rerun a command. And I think the concepts just fit nicely. There is no mental burden with this.

revert-buffer in compilation buffers

(advice-add
   #'compilation-revert-buffer
   :filter-args
   (defun mm/always-noconfirm-compilation-revert-buffer (args)
     (pcase args
       (`(,ignore-auto nil) `(,ignore-auto t))
       (_ args))))

I use revert-buffer as a consenting adult - kill and restart the compile command, without asking.

Scripts at the speed of thought

insta-script.gif?raw=true

Figure 2: Make a script, and run the script. Leveraging bash-completion in shell-script-mode.

mememacs/create-script

(defun mememacs/create-script* (file bang setup)
  (find-file file)
  (insert bang)
  (save-buffer)
  (evil-insert-state)
  (set-file-modes file #o751)
  (funcall setup))

(defun mememacs/create-script (file)
  (interactive "Fnew script: ")
  (mememacs/create-script*
   file
   "#!/bin/sh\n"
   #'shell-script-mode))

(defun mememacs/create-bb-script (file)
  (interactive "Fnew bb: ")
  (mememacs/create-script*
   file
   "#!/usr/bin/env bb\n"
   #'clojure-mode))

I have bound these in dired-mode. Then, I use mm/shell-command-on-file to dev interactively sort of.

Btw shell-script-mode becomes a power house when you integrate shellcheck. flycheck has something for that. (pretty sure flymake should as well.) Shellcheck makes superb warnings. Firmly in my "adopt" circle.

bash-completion in sh-mode

Here is my full bash-completion config that adds to capf.

(use-package bash-completion
  :config
  (bash-completion-setup)
  (setf bash-completion-use-separate-processes t)
  (defun bash-completion-capf-1 (bol)
    (bash-completion-dynamic-complete-nocomint (funcall bol) (point) t))
  (defun bash-completion-eshell-capf ()
    (bash-completion-capf-1 (lambda () (save-excursion (eshell-bol) (point)))))
  (defun bash-completion-capf ()
    (bash-completion-capf-1 #'point-at-bol))
  (add-hook
   'sh-mode-hook
   (defun mm/add-bash-completion ()
     (add-hook 'completion-at-point-functions #'bash-completion-capf nil t))))

Oh async-shell-command, my trusted friend

Of these commands, it is the one I use the most. The other commands could be performed in terms of it. Here is some of my journey smoothing out some edges.

Put the command into the buffer name

When you run a second command, by default, it tries to reuse the old buffer and asks you

(yes-or-no-p
 (format
  "A command is running in the default buffer.  %s? "
  action))

I put the command into the buffer name so I usually get a unique buffer name.

(setq async-shell-command-buffer 'new-buffer)

  (defun path-slug (dir)
    "Returns the initials of `dir`s path,
with the last part appended fully

Example:

(path-slug \"/foo/bar/hello\")
=> \"f/b/hello\" "
    (let* ((path (replace-regexp-in-string "\\." "" dir))
           (path (split-string path "/" t))
           (path-s (mapconcat
                    (lambda (it)
                      (cl-subseq it 0 1))
                    (nbutlast (copy-sequence path) 1)
                    "/"))
           (path-s (concat
                    path-s
                    "/"
                    (car (last path)))))
      path-s))

  (defun mm/put-command-in-async-buff-name (f &rest args)
    (let* ((path-s (if default-directory (path-slug default-directory) ""))
           (command (car args))
           (buffname (concat path-s " " command))
           (shell-command-buffer-name-async
            (format
             "*async-shell-command %s*"
             (string-trim
              (substring buffname 0 (min (length buffname) 50))))))
      (apply f args)))

  (advice-add 'shell-command :around #'mm/put-command-in-async-buff-name)

Now I can complete buffers and start typing the commands. And the buffers don't have an anonymous name like *async-shell-command<2>*.

shell-command–same-buffer-confirm

Sort of a power setting when you do async-shell-command a lot. Nowadays I do:

(setf async-shell-command-buffer 'new-buffer)

If I want to kill I can do C-c C-c on the old buffer.

shell-mode as a terminal emulator

(defun mm/shell-via-async-shell-command ()
    (let ((display-buffer-alist
           '((".*" display-buffer-same-window))))
      (async-shell-command shell-file-name)))

You get a shell buffer running your shell. Does everything I need from a terminal. It pays of having a minimal .rc file. This is also why I have shell-file-name set to "/bin/bash". Even though I have a cool zsh config with vi mode. I get all emacs editing power in that shell buffer.

The next layer on the cake

More context for shell-command.

project

I use project.el. project-compile runs compile in the project root. Analogously, there is project-async-shell-command. projectile, a big and widely used package, provides similar commands.

recompile

Similar to going to the *compilation* buffer and revert-buffer. But a single command.

Ansi colors for comint

If you use Koacha together with compile, you will get output sprinkled with ANSI (color) escape codes.

Bit cluttering on the eyes.

I knew from earlier dabblings that there is a package called ansi-color. So I checked around on how to make my buffer colored nicely.

Turns out that comint already has ansi-color-compilation-filter setup by default. Checking the code for compile I see that with prefix arg, the buffer becomes a comint buffer. So I decided I always make my compile buffers comint buffers.

(advice-add
   'compile
   :filter-args
   (defun mm/always-use-comint-for-compile (args)
     `(,(car args) t)))

Koacha output looks like this:

5vpmnsu.png

Figure 3: A compile buffer running Koacha with pleasing green colored output text.

Levers are great

Ssh

Nice tip in case you did not know: You can define preset configs in ~/.ssh/config and they will show up as bash completions when you type ssh and hit tap.

Host dotomic-system-ec2
     HostName ...
     ...

So now I just type M-& for async-shell-command, then ssh, then I hit tap and I get dotomic-system-ec2 as completion. Yes!

Embarking

Through embark the power of completions is further amplified. For instance, I can complete git branches via git checkout completions.

embarking-git-branches.gif?raw=true

Figure 4: Abusing read-shell-command to dispatch with embark on git checkout completions. Invoking embark-insert as an example.

Pass

Another example. I used to use helm-pass for pass. Guess what, pass has great shell completions. I get a free interface to pass just with async-shell-command.

Particulars

shell-file-name

It matters. For instance, if you use "/bin/bash" and you set up your path in a zshrc that might be a pitfall. Another thing that happened to me was that keychain was prompting for my ssh password inside the bash-completion process, making it hang.

Troubleshoot

  1. can you start `bash` and have completions? (on arch, maybe you want to install bash-completion).

Date: 2022-09-22 Thu 12:32

About
Contact
]]>
https://faster-than-light-memes.xyz/extending-your-reach.html extending-your-reach 2023-01-01T23:59:59+00:00 extending-your-reach

ftlm

extending-your-reach

Introduction

Putting love into your setup will pay off.

When your mind becomes one with the computer. When it starts feeling like it is expanding your reach. This is where the computer as a tool starts unfolding its true potential.

MbnkaGg.jpeg

Figure 1: Linux user reaching into the computer, becoming one with the computer. In space. A tomato. A fork. The stars.

A real tool is part of your mind and body

The mind tracks the space around us that we can grasp and manipulate

I was recently learning a bit about peripersonal space and the connection to tool usage.

Our mind is tracking the space around us, importantly specifically the space we can interact with.

When this is broken via strokes or developmental issues, the person bumps into things and can not use tools well. 1

From the introduction of a paper on the topic:

Peripersonal space is the multisensory space immediately surrounding our body, or more specifically the sector of space that closely surrounds a certain body part (Rizzolatti et al., 1981, 1997). A crucial factor that distinguishes the perception of our immediate surroundings from that of more distant space is our potential ability to interact with (i.e., to reach and grasp, or to avoid) objects within peripersonal space. Electrophysiological studies in macaque monkeys suggest that multisensory peripersonal space is represented in body part-centered coordinate frames, within both subcortical structures (the putamen), and in cortical regions of the frontal and parietal lobes (Hyvärinen, 1981; Rizzolatti et al., 1981; Colby et al., 1993; Graziano and Gross, 1993)

One cool aspect of this is that our internal map of the space grows and shrinks with whatever tools you use.

From Maravita A, Iriki A (2004):

What happens in our brain when we use a tool to reach for a distant object? … research suggests that this extended motor capability is followed by changes in specific neural networks that hold an updated map of body shape and posture (the putative "Body Schema" of classical neurology). These changes are compatible with the notion of the inclusion of tools in the "Body Schema", as if our own effector (e.g. the hand) were elongated to the tip of the tool.

This is when you have a pen or fork in your hand and you can move it as if this was part of your body.

Similar: You drive a car and it is as if you take on the shape of the car.

Reach into the computer, or reach somewhere else, ssh'ing into a server

Here is what I think happens if you use your computer right:

When you can navigate and interact with the computer effortlessly, it can feel like you are extending your body and mind into the digital realm, reaching out to grasp and manipulate the vast expanse of information and tasks at your fingertips.

This feeling of expansion and reach is not just a metaphor - it is a citizen of the mind that comes from utilizing the natural structures in our brains that have evolved for tool usage. It is the same confidence and efficiency we feel when picking up a tomato with a fork.

What I am saying is that when you have this mind-expanding and reaching thing going; You are using the tool usage hand coordinate parts of the brain.

It is not that a clunky and cluttered computer experience is the worse tool and a keyboard-driven, smoothed-out experience is a better tool.

It is that the smoothed-out experience is a real tool and anything else you do with a computer is just something you are waging battles with.

If it expands your mind, it is a real tool.

Which tools?

(You can achieve this otherwise, I just want to be more concrete about example technology rather than staying on the philosophy of tool usage level). This technology does the mind-expanding stuff for me: Linux, emacs, a good package manager pacman, a tiling window manager with a lisp REPL stumpwm, qutebrowser at least for the surface level of the web.

One way to get stuff under the fingertips is to have an emacs package for it, this is sort of the infrastructure that allows reach: Files - dired, Git - magit, Notes - denote, Remote files and shell - Tramp, email - mu4e.

In general, growing by removing makes for more control and focus.

The one thing in my daily life that is like a block of UI that I cannot reach into is the slack client. I wish I would be able to have an emacs interface. (emacs-slack doesn't work last time I checked because slack changed how their tokens work. They don't want alternative clients for some reason).

This is also an aspect of the REPL I think

When you have a lisp program running with a REPL you get this reach for the process and (more or less) the entities in the process. Doing this together with the source code (I mean eval-last-sexp and friends) makes the source code come alive. The process becomes a tomato I can move around with my fork. This mind-expanding nature of the REPL is one of its magics. 2 Because this is a tacit process, it is impossible to convey it via words. Similarly, I cannot convey what music does or how it is to ride a bike.

Footnotes:

2

There is a lot more to say. A big aspect is instant feedback, it makes it so you do not have to mentally track uncertainties. You know that each form you are crafting works (You def an example input and code your forms 1 by 1). To follow this thread of philosophical inquiry into Lisp development, see Paul Graham On Lisp and Hackers and Painters.

Date: 2023-01-01 Sun 20:03

About
Contact
]]>
https://faster-than-light-memes.xyz/emacs-clojure-lispy-mind-meld.html emacs-clojure-lispy-mind-meld 2023-04-24T23:59:59+00:00 emacs-clojure-lispy-mind-meld

ftlm

emacs-clojure-lispy-mind-meld

Table of Contents

My first screencast of programming Clojure.

Website

Have you ever thought, I just want to flip a coin? You might have landed on a few bloated websites filled with commercial bullshit.

I thought this is a good chance to make a video while I program something.

Lispy

Thanks to Mr. Oleh Krehel aka abo-abo. This package is truly magnificent and a big part of my Emacs feel and power.

Keep in mind that Lispy has a steep learning curve. Comparable to vim-bindings coming from non-modal editing. The payoff is a world of editing s-exp at the speed of thought. It is raw power.

Being able to modify lisp, interleaved with evaling it, is a profound and mind-expanding experience. It is the real deal of feeling and knowing the competence of the computer.

  • lispy
  • see Meow for my config, I have interleaved the two.

Meow

After using Evil for years, the desire in me grew to use something more bare bones. What pushed me over the edge was realizing that evil-search was a second implementation of what isearch, a truly magnificent library, already covers.

I think Evil is great and maybe also the place to start, because there is a lot of lore for Vim beginners, intermediates and masters.

Meow shares with Vim modal editing. It too is uncompromisingly built for power users.

Meow is like a pair of skates that allow you to ride the Emacs builtins.

This design is reified in the keypad concept, which allows you to run default Emacs bindings. Using the leader-key paradigm, which we got from Spacemacs and indisputably a great idea.

github

My init-meow.el, polished and being polished to my taste and needs.

Stumpwm

Lisp (and Smalltalk, I suppose) are a profound discovery of humanity. In a way, I believe the power of Emacs is just the power of Lisp, molded into a tool for thinking and computer usage.

The first time started Stumpwm and went through the Getting Started, I immediately had the feeling in my bones this is my wm.

Basically in the second paragraph, they say how to open Emacs :).

I REPL into Stumpwm with sly and build a few of my own window management commands.

Like emacs, maximal in its capability and minimal in its presentation. It lets me get everything else out of the way so I can focus on emacs.

Defining commands that optionally call through to Emacs gives me a new level of fluidity making the system feel like made of water and out of one whole. The only thing better than that is having EXWM, but this comes with its own tradeoffs. With Stumpwm I enjoy a truly solid and trustworthy x client implementation.

See also

Date: 2023-04-24 Mon 08:25

About
Contact
]]>
https://faster-than-light-memes.xyz/bobscheme-1.html Bobscheme 2023-07-05T23:59:59+00:00 Bobscheme

ftlm

Bobscheme

Sometimes you just want to implement a Lisp using JSON data on dotnet.

Github code

Mainstream programmers understand the value prop of JSON, the internet is built with it. JSON comes from Javascript being conceived as a Scheme, which got its dynamic data structures from IPL.

The important part of a language is the ideas, what is idiomatic, and what you can express. The kinds of thoughts you are thinking with it. The syntax is the least important part of a language, seriously. JSON allows me to express Lisp code, because I only need to say lists, and atoms - numbers, symbols.

I am implementing a SICP metacircular evaluator. There are functions, there are values, you can call functions on values and you get a value back. There is also reference type atom, which is more or less the one from Clojure.

I can ask ChatGpt to produce Bobscheme, I can read and modify Bobscheme ad-lib. After all, it is just JSON. We know how to read, modify and create JSON.

They, who understand Bobscheme are but a small step away from understanding Lisp and Clojure.

Foo Accumulator

This Bobscheme code defines a function called make-adder. This function returns a function object, that accumulates the sum of all the args it was called with. Paul Graham was describing this function as a small example code snippet to get a feel for the power of a language (2002).

[
  "define",
  "make-adder",
  [
    "lambda", ["n"],
    [
      "let",
      [
        "state", ["atom", "n"]
      ],
      [
        "lambda", ["i"],
        ["swap!", "state", "+", "i"]
      ]
    ]
  ]
]

Def a machine:

["define", "machine", ["make-adder", 0]]

Use the machine:

["machine", 10]

=> 10

["machine", 15]

=> 25

The Bobscheme code is almost the same as the Clojure code:

(defn make-adder [n]
  (let [state (atom n)]
    (fn [i]
      (swap! state + i))))

Because the ideas are the same, we get to call that dialects of Lisp.

The Bobscheme is just annoyingly bloated with commata and quotation marks, inheriting from its JSON notation heritage.

Bobscheme part 3 - Local Environment, Let foo be bar!

Skipping some episodes where I made lambda and macros work.

I was thinking about lying in bed and how let could work and it shows in how quickly I put the code I think.

This time I tried to cut out a functional chunk. Program. cs now has a function called IsLet and is now called EvalLet.

I chose the same default sequential semantic that Clojure uses for my let bindings. In Emacs Lisp and Common Lisp, this would be called "let*".

Clojure, Lisp, Json, Scheme, Interpreter, joyful, hacking, hacker, Emacs, fun with the computer, lisp evaluator, chat gpt

  Object EvalLet(JToken expr, ImmutableDictionary<String, Object> env)
{
    var letExpr = expr.Skip(1);
    var bindings = letExpr.First().ToObject<JArray>();
    var localEnv = env;

    for (int i = 0; i < bindings.Count(); i += 2)
    {
        var nameExpr = bindings[i];
        var valueExpr = bindings[i + 1];

        if (!IsSymbol(nameExpr))
       {
            throw new Exception("Expected symbol for binding name in let: " + nameExpr);
        }

        var name = nameExpr.ToObject<String>();
        var v = Eval(valueExpr, localEnv);
        localEnv = ExpandEnv(localEnv, name, v);

    }

    var bodyExpressions = letExpr.Skip(1);
    return EvalSequence(bodyExpressions, localEnv);
}

This bob scheme code

["let", ["bar", 10,
         "foo", ["+", "bar", 100]],
 "foo"]

says 110.

Part 2 - global env, variable lookup, little emacs things

I settle on a string atom representation.

This is the symbol foo:

"foo"

This is the string "foo":

"'foo"

So hello world in Bobscheme is:

"'Hello, world!"

Then I add a global environment, assignment and variable lookup, and at the end of the episode I can say:

["define", "foo", 10]

=> foo

"foo"

=> 10

In between I ramble about Lisp and Emacs things.

Keywords: Lisp, Scheme, Dotnet, C#, .Net, Csharp, JSON, Newtonsoft, LINQ, SICP, The structure and interpretation of computer programs, metacircular evaluator, own evaluator, own language, personal language, how to, emacs, screencast, programming, coding, showcase, showing off, Lisp explained, scheme explained, evaluator explained, emacs obarray, emacs variables, debug on variable change, trace-function, emacs theme, down to code, fun programming, global environment, variable lookup, immutable dictionary

Part 1 - dotnet new console, REPL

I make a program that reads JSON and then evaluates it using the meta-circular evaluator from the structure and interpretation of computer programs.

In this episode, I get to self-evaluating forms. So I can say "Hello, World!".

The cutest thing about Bobscheme is the prompts I use for the REPL.

string[] prompts = { "user> ", "what next?> ", "what is my purpose?> ", "say the next piece of the program> " };

They set the tone for joyful, toyful programming. Also doesn't this just clear up so much about the interaction of the programmer with the program?

Keywords: Lisp, Scheme, Dotnet, C#, .Net, Csharp, JSON, Newtonsoft, LINQ, SICP, The structure and interpretation of computer programs, metacircular evaluator, own evaluator, own language, personal language, how to, emacs, screencast, programming, coding, showcase, showing off, Lisp explained, scheme explained, evaluator explained

Date: 2023-07-05 Wed 08:38

About
Contact
]]>
https://faster-than-light-memes.xyz/a-system-like-water.html a-system-like-water 2023-01-01T23:59:59+00:00 a-system-like-water

ftlm

a-system-like-water

I want to use my computer at the speed of thought. I want my mind to reach into the realm of files and websites and ssh servers and do things the way I am doing things with objects in the real world.

Here is the one thing that will make your setup instantly feel much more like water.

This setting changed my life. If I had discovered it later I would have wished I had discovered it earlier. I had it from one of Luke smith vim videos.

You put this in .xinitrc.

xset r rate 120 250

This controls how quickly you are repeating your key after holding it down.

The first specifies the delay before autorepeat starts and the second specifies the repeat rate.

If you use vim bindings j/k are now the way you can scroll. Oh yeaa. This feels sooo smooth - like water.

Once you get used to this going back will make your fingers feel like they're wading through molasses.

Start with

xset r rate 200 200

or something. You need to build up your ability to hit keys quickly. I needed to slowly increase the numbers for this.

Date: 2023-01-01 Sun 18:40

About
Contact
]]>
https://faster-than-light-memes.xyz/the-deeper-chat-gpt.html the-deeper-chat-gpt 2022-12-13T23:59:59+00:00 the-deeper-chat-gpt

ftlm

the-deeper-chat-gpt

Notes on chat-gpt discoveries.

Updates since first version of the post

  1. They improved the websites, my session rarely resets anymore (also chats are saved).
  2. You probably need these fixes for "Network error" anymore, they changed it so you get your long answers, just takes a bit longer
  3. I have some emacs bindings for openai api now here.

Introduction

When a child first learns how to draw with colored pens, a world of possibility is opened. Every new picture is a chance for them to explore and experiment with different techniques and ideas. The pens give them a sense of control and creativity as they bring their thoughts to life on paper. The child might proudly show off their creations, going back and forth between drawing and exclaiming Look what I have drawn!

When I interact with chat-gpt I constantly have this urge to show (hence some of the stuff further down in the post).

I was also starting to dream along the lines of My body is a language model and I want to coax it into doing something. The feel of this is like there is a certain intelligence on the other end, that you can feed the right information to make it grow in some direction.

The psychology of interacting with it is somewhere on a cross-over of pet, houseplant in fast-forward mode and having a text chat with somebody on the moon - works only to some degree.

Formating in this post is like this:

prompt

Answer by chat gpt

Token limit for a single message

I pasted my blog post binaural beats using scittle. Into chat-gpt. It responds like this:

The above text appears to be the introduction to a blog post about binaural beats and their potential benefits…

It seems to only summarize the first part of the post.

what is the last sentence of the above text?

The last sentence of the above text is: ~These beats are thought to originate…

If it doesn't completely make something up in this answer this would point towards that there is a cut of your message input. In this case around 3.7k characters. Maybe it is 4000 characters, then.

I find that even if your session is reset for some reason - happens a lot currently, as the side goes down, or you hit rate limits - you can recover your session by pasting back your previous prompts / the conversation.

What I type is precious, it takes me effort to type. My default mode of writing prompts for chat-gpt is keeping what I type in files that are source controlled. Else there would have been very sad moments of loss for me when a thread resets.

Here is an implementation of copying a good chunk for chat-gpt from your buffer.

(defun kill-for-chat-gpt ()
  (interactive)
  (kill-new
   (buffer-substring
    (point)
    (cl-loop
     for i below 3500
     while (not (eobp))
     do (forward-char 1)
     finally return (point)))))

The fun so far

code

I have solved day 13 of Advent of code with chat-gpt. (code). I pasted the description of the alg and said solve this using Clojure or some such. It then made a function that was sort of correct. I needed to fiddle around a little with it.

It also works quite well when you ask random programming questions like Implement a function to check if a number is divisible by a number n in Clojure.

science edges

Sometimes you have a question in your mind that requires quite some knowledge from different fields and is not to google. This reminds me of the But Why podcast.

It was one of these questions on my mind: Is the rainbow that bees see different?.

Behold a new kind of power:

Summarize how bees see a rainbow. Is it thicker or does it have more colors? Throw in a Richard Feynman quote about refraction. Do it in victorian speech style like sherlock holmes.

My dear fellow, have you ever stopped to consider how a bee perceives a rainbow? You see, unlike us humans who possess three types of cone cells in our eyes, bees have only two. This allows them to see a limited range of colors, with an affinity for blue and ultraviolet hues. Therefore, when it comes to rainbows, it is possible that they may not be able to perceive as many colors or that the colors may appear less vibrant to them.

As the esteemed physicist Richard Feynman once posited, The rainbow is not a thing, it is a manner in which things behave. This statement highlights the ephemeral nature of rainbows, which are formed when light is refracted through water droplets. The exact colors and intensity of a rainbow can vary depending on the size and shape of the droplets, as well as the angle at which the light hits them.

In conclusion, while bees can indeed see rainbows, their perception of them may be altered due to the unique structure of their visual system. The exact colors and intensity of a rainbow may vary depending on the specific conditions at the time of observation.

I asked it about a 4 dimensional rubics cube and it answered intelligently, too. It also feels like it staying honest about what things it knows about and what it doesn't.

long output

It currently dies sometimes with long outputs saying Network error. That is really annoying and I end up resetting the session.

idea 1: You say something like Only tell me part 1 and later Respond with the rest of your answer.

idea 2: You tell it to base64 encode it's output. Tried it once and it didn't do it.

wizard scientists

I told it I am developing a hard fantasy magic system based on science. Then fed it ideas about my world and the magic. Turned out kinda cool. It starts being able to generate text of what a wizard scientist might say. The magic system is based on lisp with a clojure dialect. The wizards are then discovering and studying the magic, and discovering the magical language lisp.

After a while of feeding it with musings about my fantasy world it produced text like this:

I was a young wizard scientist already knowing spells at age 12. After a few months that the magicla academy a mentor wizard wanted to show me a beatiful experi

ment in the reticulum. We stood before a large magical artifact, shaped like a crystal ball. My mentor placed his hand on the ball and began to chant a spell in the ancient language of lisp.

As he chanted, the crystal ball began to glow with a soft, golden light. My mentor gestured towards the ball, and I watched in amazement as a small fireball appeared, swirling inside the crystal.

You see, my young apprentice, my mentor said, the reticulum is a wondrous thing. It allows us to manipulate the very fabric of reality, using the power of magic and the ancient art of lisp.

I nodded, feeling a sense of awe and excitement. I had always been fascinated by magic, and now I was beginning to understand its true power.

But remember, my mentor continued, with great power comes great responsibility. The reticulum is a delicate thing, and it must be treated with care. If we use it recklessly, we could cause great harm to ourselves and others.

I nodded again, taking his words to heart. I knew that I had much to learn, but I was determined to master the art of magic and unlock the secrets of the reticulum.

ment involving a magical animal. The mentor took me to a large laboratory, where I saw a magical bat hanging upside down from a perch.

The mentor explained that this bat had the ability to fly at incredible speeds, using its powerful wings and magical abilities. He then showed me a spell that he had been working on, which would allow us to observe the bat's movements in slow motion.

I was amazed as the mentor cast the spell, and the bat suddenly slowed down, its wings flapping lazily as it hovered in midair. We were able to watch as the bat shifted its wings and body, adjusting its position to maintain its balance.

The mentor then asked me to try the spell myself, and I was able to successfully cast it on my first try. I was thrilled by the experience, and I knew that I had just begun to unlock the true potential of the reticulum.

I continued to study and experiment with magic, learning new spells and honing my skills. I eventually became a respected wizard scientist, known for my knowledge and expertise in the magical arts. I continue to explore the mysteries of the reticulum, always seeking new and greater insights into its workings.

The model has a high temperature so it comes up with random things as well. You can put the same prompt and expect different answers. A temperature of 0 would mean it is deterministic.

Then you can always swap your medium, the ideas stay the same.

Give me some clojure reagent code that visualizes the concepts of this thread.

Output: Here is an example of how you might use clojure reagent code to visualize the concepts of the reticulum and its magical abilities:

  (ns my-app.core
    (:require [reagent.core :as reagent]))

  ;; define a component for the reticulum
  (defn reticulum []
    [:div
     [:h1 ~Reticulum~]
     [:p ~The reticulum is a vast network of magical information, where symbols and spells flow like rivers of energy. It is the foundation of our magical abilities, allowing us to manipulate the physical world in ways that would be impossible without its power.~]
     [:p ~The reticulum uses a dialect of the lisp programming language, which allows us to define symbols and functions that can be invoked to cast spells. For example, we can define a fireball function like this:~
      [:pre ~(defn fireball [radius]
         (* radius 2 pi))~]]
     [:p ~This simple function takes the radius of a desired fireball and calculates its area. We can then use this function to cast a spell and create a fireball of any size we desire. To do so, we simply need to invoke the fireball function with the desired radius:~
...
      [:p ~The reticulum also allows us to create more complex spells, such as teleportation and mind reading. These spells require a deep understanding of the lisp language and the underlying principles of...

There are no limits to the level of detail. For me as a d&d world building geek that never actually did play d&d, this is amazing:

Magical Gemstone Manipulation - an Introduction. This textbook is an introductory text Chapters:

Introduction to Gemstones and their Properties

Types of Gemstones and their Uses in Magic

Gemstone Cutting and Shaping Techniques

Gemstone Enchantment and Infusion with Magic

Gemstone Crafting and Design

Advanced Gemstone Manipulation and Applications

Ethics and Responsibility in Gemstone Magic

Case Studies and Examples of Gemstone Magic in Practice

Further Study and Exploration of Gemstone Magic

The textbook would include chapters on the different types of gemstones, their properties and how they can be used in magic. It would also cover techniques for cutting and shaping gemstones, as well as the process of enchanting and infusing them with magic. Additionally, the book would discuss the ethics and responsibility of using gemstones in magic, and provide case studies and examples of how gemstones are used in practice. The book would be suitable for both beginners and more experienced practitioners of gemstone magic.

Here is some imaginary Clojure code from an imaginary wizard science class about my imaginary magic.

"But the true power of the reticulum comes not from individual spells like the fireball function, but from the ability to combine and manipulate these spells to create more complex and powerful effects. For example, we can use the teleportation function to transport ourselves or objects from one location to another:"

(defn teleportation [target location]
 ;; complex lisp code to transport target to location
  ())

"We can then combine this teleportation function with other spells, such as the shield function, to create a powerful defensive spell that can protect us from harm:"

(defn protective-shield [radius strength duration]
  (let [shield (shield
                radius
                strength
                duration)
        teleport (teleportation target location)]
    ( ;; combine shield and teleport spells to create protective shield)
     )))

I formatted the src blocks, they were all clumped up. The src blocks are the same style as the examples I gave it further up in the prompt.

uncovering

Trying more advanced fixes for Network Error.

Prompt try1 1:

Here are some rules you should follow from now on:

Instead of answering with your answer text; Answer with a high level overview of your answers.

The overview should have the form of the output of the linux tree shell command.

Your possible answers represent files in the imaginary output.

From then on, when I say tree, print a tree of the current concepts of the conversation. Each file is an answer that you might give. The files have short descriptive names of their content.

When I say less <filename> you print the first 50 lines of that answer. When I then say j you print the next 50 lines. When you reach the end of your answer you print a line like <filename> ends here.

Do you understand these rules?

Lol, I feel like I made it reveal a deeper layer of its programming, check this:

Yes, I understand these rules.

Here is a tree of my possible answers:

.
├── yes
├── no
├── i_dont_know
├── i_dont_understand
├── i_am_a_computer_program
└── i_am_not_able_to_brows_the_web

To view the contents of a file, you can use the less command followed by the file name. For example, to view the first 50 lines of the yes file, you would type less yes. To view the next 50 lines, you can type j. When you have reached the end of the file, the program will print a line indicating that the file ends there. For example, if you have reached the end of the yes file, the program will print yes ends here.

Now this could be and I think is it just making things up, fugazi. But I suspect that they have a hidden prompt from where those come from. A user of chat-gpt is at this point familiar with the ever-present possibility of i_am_not_able_to_brows_the_web.

code

It can do code, although as you might expect you still need to put it together and make it work. For me, it currently outputs a lot of Clojure code that is not quite right. Putting locals into a let that was supposed to be in loop for example.

I already started having the effect of thinking I want to do x, I ask openai how to do x. This must be how it is for google driven developers and I can say that is a step down from reading the manual / docs on how to achieve it. The most powerful path is one of nuance, using it where it is useful but not making your thinking reliant on it. Else you stop thinking for a while waiting for the prompt to come back. - that would be a horrible thing to get used to.

New kind of interface

The bee rainbow example is the use case of a conversation interface to the world's knowledge. This is currently hampered by the fact that you might get I cannot browse the web answers.

But I think in principle that is super promising. Imagine building a program feeding it some science data and you get a conversation interface where you just ask it for trends in the data.

In programming, I could feed such a thing to my repo and then ask it things like make a listing of the domain model of this code and things like this. (See the tree rule example).

other tips

You can just stop in the middle of

It might then continue with your text.

Here is what an old wizard in a hard fantasy world might say about magic: You have to undestand the intricacies of the elements that

compose magic to wield it effectively. Magic is not something that can be easily learned or mastered; it takes years of study and practice to understand its complexities and tap into its power.

The key to using magic effectively is understanding the fundamental principles…

  • Typos don't matter so much. Just get across what you want to say.
  • If you do something like building up ideas about a fantasy world, you can randomly paste snippets of text, they don't necessarily need a logical continuation.

Conclusion

This is a fascinating new kind of tool/thing in the world.

It can generate text after you put in ideas/examples/ prompts that it can work with. You can build up some context, which makes it so sad right now when your session gets broken. At times it feels so precious I have it doing this thing now. Like some special place that you went to together with it.

If you had shown this tool to someone 10 years ago, they would have thought it was science fiction. Many people might have said that AI couldn't have such a high level of understanding. They were wrong then, and they are still wrong now about what the next advancements in AI will be.

The website interface and the restrictions are annoying. True power will come from having a truly open (free?) version of this that is my own and that I can hack on. I want this in Emacs, I want my prompts source controlled, and I don't want weird and made-up restrictions that make it just annoying 2/10 times.

The real advancement that I feel over chatbots from 5-10 years ago is that it keeps the ideas and concepts in a conversation.

In a similar conversation to the above if I would say j out of context: (yes there is a typo it even keeps that straight, lol)

I'm sorry, but I don't have any more information to provide for the file acknoledged. As I mentioned earlier, when you say less <filename>, I will print the first 50 lines of that answer. If you then say j, I will print the next 50 lines. Since the file acknoledged only has one line of text, there are no additional lines to print.

├── acknoledged

Here is the tree structure again, showing that the file acknoledged is the only file available at this time. If you would like to see the first 50 lines of this file, please say less acknoledged. Otherwise, please ask a new question or provide a new request.

I had a few moments while interacting with it where I feared it dropping the concepts or being confused about things. But it never was. It turned around in the next sentences and clarified that it is still on track.

Since it is simulating conversation, you feel some of the limits in your conversation parsing part of the brain. It is like it has a certain psychology. If it becomes the perfect tool, the annoying bits will be replaced with the quiet competence of a computer.

Footnotes:

1

Here is a further version of this prompt.

Here are some rules you should follow from now on:

Instead of answering with your answer text; Answer with a high level overview of your answers.

The overview should have the form of the output of the linux tree shell command.

Your possible answers represent files in the imaginary output.

From then on, when I say tree, print a tree of the current concepts of the conversation. Each file is an answer that you might give. The files have short descriptive names of their content.

When I say less <filename> you print the first 50 lines of that answer. When I then say j you print the next 50 lines. When you reach the end of your answer you print a line like <filename> ends here.

Do you understand these rules and can you follow them? Answer with acknoledged

When I pasted the (incomplete) conclusion of my blog post it answered with this. And yes, asking less limitations will make it output what you expect.

.
├── blog_post_conclusion
    ├── praise_for_tool
    ├── limitations
    └── potential_improvements

The above tree structure represents the high-level overview of the conclusion to the blog post. The blog_post_conclusion file represents the overall conclusion of the post, while the praise_for_tool file represents positive comments about the tool and its capabilities. The limitations file represents any limitations or challenges with the tool, and the potential_improvements file represents suggestions for how the tool could be improved in the future. To see the first 50 lines of any of these files, please say less <filename>. For example, to see the first 50 lines of the blog_post_conclusion file, you would say less blog_post_conclusion.

Date: 2022-12-13 Tue 16:47

About
Contact
]]>
https://faster-than-light-memes.xyz/backing-you-up.html backing-you-up 2022-10-14T23:59:59+00:00 backing-you-up

ftlm

backing-you-up

File backups are useful. It happenend more than once to me that I found something in a backup somewhere from 2 months ago that did no end up being commited in git.

Frequent file backups will make you more relaxed.

53XOl25.jpg

Figure 1: Vast open sky! Sun and clouds. high tech fantasy city guild wars afrika flying buildings waterfalls flowers. little rainbows

backup-each-save

Saving buffers is a great joy of life.

With backup-each-save, each save also makes a backup file in a backup dir.

config:

(use-package backup-each-save
  :config
  (add-hook 'after-save-hook #'backup-each-save)
  (setf make-backup-files nil))

Lol, this is how the backup dir looks for this file I am currently modifying.

-rw-r--r--  1 benj benj  858 Oct  4 16:06 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_06_00
-rw-r--r--  1 benj benj  916 Oct  4 16:06 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_06_50
-rw-r--r--  1 benj benj  935 Oct  4 16:07 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_07_21
-rw-r--r--  1 benj benj  937 Oct  4 16:07 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_07_45
-rw-r--r--  1 benj benj  959 Oct  4 16:08 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_08_05
-rw-r--r--  1 benj benj 1.1K Oct  4 16:10 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_10_08
-rw-r--r--  1 benj benj 1.3K Oct  4 16:12 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_12_08
-rw-r--r--  1 benj benj 1.3K Oct  4 16:12 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_12_42
-rw-r--r--  1 benj benj 1.3K Oct  4 16:13 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_13_15
-rw-r--r--  1 benj benj 1.3K Oct  4 16:13 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_13_28
-rw-r--r--  1 benj benj 1.3K Oct  4 16:13 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_13_36
-rw-r--r--  1 benj benj 1.3K Oct  4 16:13 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_13_40
-rw-r--r--  1 benj benj 2.7K Oct  4 16:16 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_16_09
-rw-r--r--  1 benj benj 2.7K Oct  4 16:16 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_16_18
-rw-r--r--  1 benj benj 2.8K Oct  4 16:16 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_16_42
-rw-r--r--  1 benj benj 2.8K Oct  4 16:16 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_16_49
-rw-r--r--  1 benj benj 2.8K Oct  4 16:17 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_17_11
-rw-r--r--  1 benj benj 2.9K Oct  4 16:17 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_17_47
-rw-r--r--  1 benj benj 2.9K Oct  4 16:18 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_18_34
-rw-r--r--  1 benj benj 2.9K Oct  4 16:18 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_18_37
-rw-r--r--  1 benj benj 3.1K Oct  4 16:19 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_19_07
-rw-r--r--  1 benj benj 3.1K Oct  4 16:19 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_19_10
-rw-r--r--  1 benj benj 3.1K Oct  4 16:27 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_27_36
-rw-r--r--  1 benj benj 3.1K Oct  4 16:27 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_27_54
-rw-r--r--  1 benj benj 3.1K Oct  4 16:28 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_28_10
-rw-r--r--  1 benj benj 3.1K Oct  4 16:28 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_28_16
-rw-r--r--  1 benj benj 3.2K Oct  4 16:28 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_28_52
-rw-r--r--  1 benj benj 3.2K Oct  4 16:31 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_31_40
-rw-r--r--  1 benj benj 3.3K Oct  4 16:31 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_31_48
-rw-r--r--  1 benj benj 3.4K Oct  4 16:32 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_32_34
-rw-r--r--  1 benj benj 3.3K Oct  4 16:32 20221004T160458--scratching-in-space__emacs.org-2022_10_04_16_32_40

The backup dir size doesnt matter compared to the vastness of my disk space.

Laptop:

du -h -d0 ~/.backups/
| 43M | /home/benj/.backups/ |

It just doesn't matter.

The space age

Other instances of emacs in the space age:

Date: 2022-10-14 Fri 15:33

About
Contact
]]>
https://faster-than-light-memes.xyz/the-joy-of-clojure.html the-joy-of-clojure 2023-01-26T23:59:59+00:00 the-joy-of-clojure

ftlm

the-joy-of-clojure

Introduction

We don't yet have a strong psychology and sociology of programming languages. One day we will, and we will be able to retroactively make sense of why Clojure is so powerful.

6usJE0L.jpg

Figure 1: The soul! A computer. Solar punk Clojure. The inside of a computer. Rubics cube colored gems are flying around. Lighting.

Paul Graham has suggested The Taste Test for understanding the power of a language. A programming language is a tool for thinking. Ultimately, its power comes from letting you think thoughts and express them. With sensibility (hypersensitivity), you can tell which language feels more restrictive than another.

If all languages would be the same, we would be programming assembly. But we are not, because we live in a world where languages have varying degrees of power.

Here I try to describe a few things that set Clojure apart, even from other Lisps.

What interactivity brings

With Lisp, you can quickly test each piece of code as you write it, ensuring that it is solid and functioning correctly before moving on to the next piece. This allows for a more streamlined development process and eliminates the need to keep in mind all of the potential issues that could arise with a piece of code. Additionally, the ability to quickly evaluate code and make small experiments allows for a more agile and flexible development process.

Here is a simple example:

(file-exists-p "~/.clojure/")

Are you getting the file path right? When I write Lisp, I know the answer while I am writing the program. I just eval whatever form I have to build the file path. Because of structural editing, I can wrap whatever form in (file-exists-p) quickly and experiment right then and there.

Doing little experiments is quick enough so it can mesh with your thinking. I have the freedom and agility to just do and move. We get the same power in the small during development and in the large while diagnosing a problem in production. 1

Philosophy of simplicity

Clojure first clicked for me via Rich Hickey talks. Keep things simple. Let data be data. Then you can just manipulate the essence of the stuff and be done. 2 , 3

He establishes the reasons for Clojure and the opinions on how to build things. And this permeates the culture.

The combination of data-orientedness and functional programming while making real-world pragmatic tradeoffs, lends itself to a complete4, robust, no-bullshit style.

Strong community

When I use a library I can go to the slack channel and usually the maintainers help me out. It happened to me more than once when I made a bug report, somebody fixed it within a few days. Everybody is excited about technology and wants to help you out. It ties in with the joy of Clojure as well. You get happy, friendly people. This is power. Humans are more effective when they are happy and friendly.

Not to mention Borkdude.

Non-breaking versioning

It is an explicit value (again from Rich Hickey's philosophy), to not make breaking changes. This is one of the things where once you have it, boy, you don't want to ever go back.

After acquiring this taste, getting broken because I bump a version makes me think Why are you doing this to me?.

The aesthetics of data orientedness

The core library is a huge lever because we lift everything that can be into the space of data structures, then manipulate those data structures.

Config input, REST API response, database queries, and responses. It is all the same kind of stuff once it is in our system.

I think of this as a lift and manipulate kind of lever. Unix has this with program input output text. Once you are in the realm of textual input and output you can leverage shell commands to manipulate. Emacs has the same thing with text in buffers. If you can express your domain as text in the buffer you can give it to the user for manipulation, and you can leverage the core library for manipulating text in buffers.

This data-orientedness is something I can expect from libraries and other people's code. The dominating amount of stuff will always be just data structures acting on pure functions.

Freedom and joy

The workflow is an utter joy, with the REPL at the center of it. I start a program once and it grows together with my ideas. There is something about a program that runs for days and you don't restart it that I cannot explain but it does something to your mind. The closest analogy is a kind of friendship with the program.

  • inline def some of your data, craft your code forms.
  • Functional programming (and The Value of Values)
    • able to fabricate data
    • able to get the time right with atomic successions
    • able to easily keep records of the past

I get a real kind of safety. The kind where I can sleep at night because I know my program is bug-free. You get this from there being few enough ideas in the program that you can hold the relevant pieces in your head.

Any program that is small enough to be self-evident is with a step function dramatically more likely to work bug-free. 5

It helps that everything is accessible from emacs which is the other ancient and powerful tool that feels like an extension of my mind.

Because of this focus, solidity and ease of development, I am more joyful and creative when programming with Clojure.

It allows me to focus on the actual problems. So I can spend time on getting the user experience right etc.

Summary

So here is a tool that lets me think the right thoughts and express them. It lets me move with ease where I want to be.

From Lisp, I get the interactivity and the tradition of FP and simplicity. When I want to make a small experiment with the code, I can just do a small experiment with the code.

Beyond that, there is a solid and dependable community, the data-orientedness and the leverage of targeting big platforms.

I can model information systems and can make the program just do what it needs to do, and do nothing more.

Clojure just delivers.

The silent competence of the computer.

(Marvin Minsky)

Note

I know there is a book of the same title. This is not accidental. The power of Clojure also lies in the joy it brings. An alternative title for this post could be Joy is power in analogy to Paul Grahams Succinctness is power.

Footnotes:

1

Bradford Cross has mentioned this and other things in a very convincing talk recently.

2

I believe I see hints of the same craftsmanship of getting shit done ideas in other places: Brian Will Object-Oriented Programmin Embarrassing, his counterexamples are very straightforward and complete. Chris Keaathley - SOLID code isn't flexible

3

Rich Hickeys greatest hits The start point. Get your mind expanded by simplicity and clear thinking.

4

Complete in the sense that you make a piece of code that gets the job done. Instead of scattering logic around the place.

5

Stuart Halloway has similar thoughts, Radical Simplicity. Other people like Dan Friedman also made this relatively explicit. I think at this point it is obvious that simplicity is crucial for building good software. The question is what is simplicity and how to do it?.

Date: 2023-01-26 Thu 09:48

About
Contact
]]>
https://faster-than-light-memes.xyz/conversation-1.html No Iterations 2023-07-07T23:59:59+00:00 No Iterations

ftlm

No Iterations

Lisp and Clojure enhance interactive, idea-driven programming.

One day we will boot up our computer and it asks What is my purpose?.

One magic piece of Lisp is the concept and idea of interactively building the program while it is running. The interaction layer between the program and programmer is implemented by a read, eval, print-loop, REPL. It doesn't matter so much what the REPL exactly is, what matters is the idea of an interactive interface as programmers to the running program. In the same way, we have an interactive interface to files on the computer; In Lisp, we have an interactive interface to the symbols, the methods, the fields - the stuff that your program is made out of.

Repl-driven development gives us a level of intimacy with the computer that has been described as a conversation with the program.

I cannot convey what music is in a way that you will know music. So too, I cannot convey what Lisp is about in a way that you will know Lisp. But I can try to give some clues and little hints.

There is something like music between a mind and a machine. REPL-driven development unlocks this world between programmer and program like nothing else does.

b-brain-2.png

Figure 1: A brain! banana, tomato, children block cubes ideas inside the brain. A computer with electricity at the speed of light in the universe on the other side

What is the purpose of programming languages?

If you think about programming languages you really need to think about what are they for?.1

language.jpg

A programming language is what is between you and the computer.

It is the interface between the ideas on one side and the stuff inside the computer on the other side.

Maybe programming languages are for many things but here is a list of some really important things:

  1. Expressing ideas
  2. Expressing ideas to the computer
  3. Make the computer think what I think
  4. Make the computer tell me what it thinks
  5. Change some entity in the computer (file, process, … )

The first idea is that making a big computer program is building a larger process out of smaller ones. I suppose you could truthfully say that sculptors make large shapes from stuck-together grains of clay. But that shows what's wrong with the bits-and-bytes approach. No sculptor ever thinks that way, nor scientist, or programmer. An architect first thinks of shapes and forms, then walls and floors, and only last about how those will be made.

Minsky (1984)

Data structures, language constructs, and at the very lowly bottom, syntax are the small things that are not what programming is about. The way that architecting is not about clay.

A language is there to allow us to modify, make experiments, and observe. Nothing more, nothing less.

Using this mental framework there is no fundamental difference between operating systems, programming languages, libraries, frameworks, user interfaces, and even text editors.2

These are all societies of process 3, some have collections of members with different emphases.

The hypothetical ideal language is completely out of the way. It would have infinitely small friction, infinitely small short steps and effort and wait time to make my ideas have effects on the computer. It would get rid of the clay entirely and we would raise and rise higher and beyond as architects riding the ideas.

We would be able to instantly and losslessly transfer thoughts to the computer and make the computer program change to our desire. We would use the competence of the computer seamlessly intermingled with the rest of our thoughts. Experiments would be thinking, with perfect reach, perfect control, and perfect access to the vast competencies, memories and remote connections of the computer realm. Racing at an unknown pace, building new kinds of towers of abstraction, thought, reason and creative spirit. Eventually hooked up to some constructors4, our thoughts would shape the stuff of the universe.

From this view, building ever more powerful languages is a path to a technological singularity.

Power is joy is getting shit done is having effects on the computer

The most powerful programming language is Lisp. If you don't know Lisp (or its variant, Scheme), you don't know what it means for a programming language to be powerful and elegant. Once you learn Lisp, you will see what is lacking in most other languages.

Stallman

Magic is what makes a great book great. It is something that happens in the mind of the reader, not elsewhere.

It has to do with masterful craftsmanship, with love, with the spark between people. It has to do with the right time and the right place, how could it be otherwise? A piece of magic comes together with the most masterful output of a masterful craftsperson. It needs to be the right time and place, else it would not be peak output.

We live in a world where we cannot measure magic yet. Otherwise, we could be churning out great movies, books and games.

You might not know it yet, but great software and great tools, too are subject to taste and aesthetics.5

Would it not make sense that the people talking about the most powerful language in sort of a mysterious way would allude to taste, too? If it is the most powerful language, it would be powerful because of reasons in the realm of mastery and craftsmanship. It would be because of magic, which is hard to explain and only accessible via aesthetics and taste.

What makes Emacs a superbly sick piece of software? What makes The Man From Earth a superbly sick movie?

The answer is you will know when you know. But you will not know before you know. And you will know for reasons that you have to discover yourself. But it won't be reasons that make no sense. It will be reasons that make perfect sense. Just that they are somewhere where you don't yet know how to look.

The only way to know magic for the moment is to hone our tastes and broaden our horizons.

What does it mean to develop a taste in programming? Stallman is giving a hint that trying Lisp will develop your taste.6

Let me throw in another clue; In order to know what different kinds of languages do, you should go and try the ones that are most different from what you already know.

Lisp is mentioned in this way again and again 7. It will broaden your horizon, it will stretch what you think about languages.

Can it be true? Does it not sound too good to be true? Why not? What in reality doesn't look like it is true? Is it not a fact that Emacs, a Lisp program, is a freaking psychedelic spaceship? Is it not a fact that society and mainstream are wrong about things all the time?

If Lisp is profoundly more powerful than other languages, then it will be powerful in a way that

  • Resonates with your programmer's heart.
  • You cannot know before you feel it.
  • Would be hard to explain, because it would be magic.

What is your most profound desire as a programmer? I think it is having effects on the computer.

What I am about to tell you is that there is an activity during programming that you sort of know but don't know. Current programming is stuck with a limitation that simply does not make sense.

Quick iterations are better

You want to make a quick experiment in the code. You make a little side project, and you set up some example data.

You tell your young programmers that they should value quick iterations. You go through hoops to not have to re-compile right now. And not again. And you juggle in the right amount of changes in your batch so that afterward you see point 2/5 not working, instead of point 22/100.

You suffer when you have long deployment cycles in your feedback loop.

Sometimes you wish you had put a log or breakpoint somewhere because it just happened.

What if you have a complicated thing happing somewhere on the server? What if the program is right now in a state that only if you could look at it, you would know what to fix?

Sometimes it would be great to quickly see the counterfactual quickly. What if this if goes into the other branch, does it still work? No, fuck it commit, push and tomorrow there is a bug report that x broke.

If you are faster with seeing what the program is doing, that is better.

This you know. And maybe you know from notebooks or some advanced hot reload tech what it would mean to be able to change the program while it is running.

Restart the program and the state is dropped on the floor. But if you see what it does, while it does it, that is a difference between night and day. 8

Because it matters what is between you and the program.

In the 70s, there were the MIT AI people, John McCarthy, Marvin Minsky, and the young bright-eyed hackers who later build the internet and influenced what computing is nowadays. Supported by J.S.R Licklider, who was the first person having fun in front of a computer terminal at night.9

These people had a vision of what computing can be and they knew it will be interactive.

Batch processing

In batch processing, you give a batch of punchcards to a dude, who puts them into a computer, and you get your result the next day or whatever.

If you accidentally miss a hole or shuffle some cards, too bad. Dealing with the complexities of punchcards is not what programming is about! Not at all, not even close.

It is just extra steps and extra complexity in your interface to the computer.10 It is a bigger chasm, a bigger wall, a bigger world of pain. You want your ideas to affect the computer and then there is extra stuff. This stuff should not be there.

Getting rid of the punchcards and finding a better way was a tremendous step forward in computer programming.

Extra work between ideas and computers are not good.

It is easy to accidentally enjoy the puzzle11 that extra steps might provide. Don't do it. Don't enjoy it. It's darkness. Don't enjoy the extra steps between you and the computer, it is not programming.

You should be annoyed at all the things you do that are not programming. How else could we have moved away from punchcards?

Another similar mistake is to think that pain means hard work and that it makes you a serious worker. Don't do it. Don't enjoy the wrong pain for the right reasons. Don't think that being playful is opposed to getting shit done. Otherwise, you remind me of what school is doing to the never-ending curiosity of young children.

We call brilliant programmers lazy because they are honing their tastes, to feel what is unnecessary pain. Pain is part of your programmer's intuition, your taste, your laziness.

Hence, the hackers and forward-looking people of their age fixed batch processing.

Interactive computing

Imagine you are programming, you stamp out a batch, give it to a dude and on the next day you get the error message forgot a comma.

It took brilliant people to see that this is not right. That there is a better way. That fast feedback even has any value at all.

Time-sharing was an idea for getting rid of Batch processing.

Interactive computing is in general the idea that you get instant feedback from the computer about what you do. For instance, you sit at a terminal and you type things. And the computer then answers - prints - some output. Personal computers inherited interactive programming from the visionaries of early computing.12

Minsky mentions in one of his lectures:

We tried to tell the people at IBM about time sharing and they said why don't the programmers just think?.

Meaning why don't they spend the extra effort to just code bug-free the first time?

They were so wrong. So utterly, completely, badly, painfully, laughably wrong. Make songs about it, and edge it on the doors of buildings. Remember it forever and don't make the same mistakes again. Burn it in your souls for it is a wound. It held humanity back. It was a mistake.

If we would be a bit more forward-looking and open-minded - how many times over would we be exploring the stars by now?

They thought interactive programming won't do anything. They thought the people that advocated it where just lazy and wanted to play, instead of doing serious things with the computer. And they argued in silly ways like how can the computer think if it is interrupted all the time? - A matter of implementation that was figured out.

hackers-movie-poster.png

Figure 2: bright-eyed hacker scientists Minsky, McCarthy, Licklider. joyful playful magic computers defeating the evil establishment. epic heist movie poster.

What does interactive computing have that batch processing does not have?

It is having a connection and an interface to the stuff inside the computer in a way that leverages how we evolved to manipulate and walk around in the world. It fits the human psyche. Its history stems from the urge to reach and explore inside the computer. And its effect is being able to reach into a new world. It was obvious to the brilliant visionaries of the time and it is obvious to us now, when we navigate and modify the stuff inside the computer.

To be clear, this is about what you feel when interacting with your operating system to create, move and modify files on the system for instance. When you open a browser and click things, this is interactive computing.

This is not a small thing - This is a different world we have. Interactive computing is arguably one of the most important technologies ever. And the big companies would never come up with this. Would they even have the incentive?

It is like having a spaceship where before you had hot air balloons. It is like the sun where before you had candles. It is something in the space between mind and machine, the ability to reach.

Next: Why does Lisp make the same jump for programming a program?

One of the best ideas in computer science

And maybe one of the best ideas ever, Von Neumann architecture.

Put the program into the computer memory.

A stroke of genius. Now we have a magic stone that can be loaded up with ideas and then it can be anything.

Before we had 1 machine with 1 program. What a program is and what a machine is was glommed together. Good design is about splitting things apart, and this was a beautiful and elegant design.

This in a way resonates with what Dennet calls Popperian and Darwinian creatures.13

First, you have a machine built to behave (Darwinian); A machine with a fixed program.

Then you have a machine that is built to learn (Skinnerian).

And finally (a Von Neuman machine), a machine that is built to deal with ideas (Popperian).

Because ideas, the memes, can be anything, including ideas about ideas, the Popperian machine has an open-ended future.14

Putting more ideas into memory was a very good idea.

The story of dynamic memory data continues with IPL, which was used for one of the most important early AI works General Problem Solver (1957).

In IPL, Information Processing Language, you had data dynamic in the program, in lists (made from cells). You can create lists and make it point to something else during the program etc. different from having to declare variables for everything.

You know of course what this means because you create lists and arrays all the time in your program.

Javascript is sort of a Scheme, so it has a function called print and a function called read (ok I guess they have glommed it together with eval).

Douglas Crockford discovered JSON by printing and reading javascript objects.4

If you know the power of JSON, you know the power of having dynamic data in your program. Your program is not about customers and payments, it is allowed to be a level higher. Your program is allowed to be about data structures. Data abstraction is something like SQL or dotnet LINQ, or a JSON parser. It is a language for talking about data and data transformations. map, filter, reduce don't know about customer names, they know about lists/sequences/streams, or so and so.

This is the heritage of Von Neumanns memory idea propagated forward through time and one level up. Your program is loaded dynamically into the computer, but your program is also dynamically loading data into its memory. Your program is, in some way, simulating a van Neuman machine itself.

McCarthy liked IPL but did not like how it was complected with implementation details of the computer it ran on.15 He had the idea of taking those lists and describing the computer process entirely in terms of it.

Let's take those lists, make the first thing the verb and implement a lambda calculus.

To understand Lisp, imagine you read JSON and treat the data as a command language for what your program does next.

function read(expression) ; returns jsonData
function eval(jsonData) ; returns an evaluated object

Eval is the big meaty function of your program. It needs to take that JSON, go through it and interpret the data as commands.

function print(object) ; print to the user
function repl() {
      while (true) {
         var whatTheUserSaid = readFromTerminal();
         var jsonData = read(whatTheUserSaid);
         var object = eval(jsonData);
         print(object);
      }
  }

This repl function can be the entry point and the game loop of our program. Now the user can sit at the console and interact with our language.

We define a few special operators. During eval, some stuff we have to implement in the static part of the program.

  • set - set a variable.
  • pair - make a pair, a pair of pairs then is a list.
  • first - first value in a pair
  • rest - the second value of a pair. (this can to a simple value or another pair).
  • lambda - make a function.
  • if - conditional evaluation.
  • quote - return the jsonData instead of evaling

This is a program that is simulating interactive computing. Where an operating system gives you access to files and processes. A Lisp gives you access to a society of symbols, functions, values, and data structures.

var globalEnv = {}; ; a dict, hash map, lookup table
function define(symbol,value) ; augment the global env

Make our Lisp interpreter know about the command define.

function eval(expression) {
    if (expression.first == "define") {
        var symbol = expression.second;
        var value = expression.third;
        define(symbol,value);
    }
    // ...
}

Lisp:

["define", "foo", 10]

(This is valid Bobscheme)

This is the cleaning up that McCarthy did to computer programming. Lists where the verb is that the front, no extra stuff. Put it into memory so you can modify it while it grows, Make a symbol type so you can give names to things, from inside the language. Make a function type so that functions are the same stuff as the rest of the program.

The fact that JSON is so useful comes directly passed down from IPL. All the objects nest, there are only a few kinds of objects and bottoms out at atoms. A printer and a reader come shipped by default. I know without knowing that Javascript gurus know the power of print, compared to the little machines you get from the C++ line of heritage.

McCarthy wanted to sit on a terminal and make the program do different things while he is programming it. He did not want to say up front all the variables in the system because he wanted to have something more dynamic for programming AIs.

The interactivity is at the bottom. - Hence it is called a building material.

You make a program that asks you what should be next in the program?. It is as simple as this. From this, all the goodness that makes Lisp elegant and beautiful comes. The simplicity of this enables easy-to-reason-about programs that write programs.16.

With this, we can have a conversation with the program. We can directly interact, while the program is running.

Conclusion

The power of Lisp is not quick iterations, but no iterations. Instead of iterating, in Lisp and Smalltalk we do conversation. This concept is reified in the read eval print loop.

It is enabled by the idea of putting the program into the dynamic memory of your program. This resonates with the Von Neuman architecture idea of putting the program into the memory of the computer.

Jack Rusher's bottom line is don't settle for anything with less interactivity than Lisp and Smalltalk!

Once you have in your fingers how to leverage the repl, it will be as obvious as the sky, vast and inescapable. This is better, this is simpler, and this gets stuff out of the way. This lets me use my brain the way a monkey reaches for a banana. Directly, the way I can delete and create files on my PC. I can define and undefine symbols in the program. I can make quick experiments while the program is running, without the mental distress of setting up the state.

It is the same difference that interactive computing does compared to batch processing. It is not a small step, it is not a big step, it is not a step at all. It is a different world.

Whatever that is. At this date and time, I will call it Magic.

See also

GPT-4 can produce some poetic stuff with this post as base

Imagine a painter, fervently engaged in a dialogue with her canvas. Each stroke isn't a hurried message jotted down and sent off, anxiously awaiting feedback. No, the painter watches each trail of color blend and mix under her brush, immediately seeing the effects of her choices. She tries different pressure, strokes, colors, and brushes, in a cycle of continuous creation and observation, a dance between her mind's eye and the canvas. This is her conversation with her art - immediate, beautiful, and ever-changing.

Now, consider a programmer, in front of his screen. The code portrayed is not a fixed monolith of logic. Instead, it morphs, breathes, and reacts under his fingertips, mirroring that painter's canvas. The programmer writes a line of code, and the effects echo through the system immediately, no abstraction barrier held in between. The immediate feedback enables him to stir into different directions, tease out underrepresented nuances, debug on the fly and explore new vistas of his creation.

The code is fluid under the hands of the programmer in a perpetual dance of creation, modification, and observation. It is an intimate conversation with the ideational fabric that weaves itself into existence as the program - the programmers' thought reflections observed immediately, altered rapidly, and understood fully.

This, my friend, is the spirit of interactive programming. A live, pulsating creation constantly in flux rather than fixed scrolls etched into digital stone, navigating creativity at the speed of thought inspired by immediate feedback, riding the great prairies of abstraction and thought, reaching a level of intimacy and understanding with your program that feels like a piece of music resonating with your heartstrings.

Footnotes:

2

One benefit of this view is now I am holding all pieces of language, and interfaces, to the same high standard.

React is not a framework, react is a language. Can I express myself using it?

5

This is one of these things that I think are instantly obvious to 99% of women. And the man-dominated software industry is mentioning it very little, to the point where you have to sort of convince the people that it is the case.

6

Paul Graham The Taste Test. Exactly this concept: Succinctness Is Power

7

Paul Graham, Succinctness Is Power, Beating The Averages.

LISP is worth learning for a different reason — the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days […]

Eric Raymond

8

It is indispensable for an artist to see what they are doing, while they are doing it.

https://www.youtube.com/watch?v=PUv66718DII

9

The Dream Machine: J.C.R. Licklider and the Revolution That Made Computing Personal.

I cannot recommend this book enough. It is such an amazing ride through the history of computers.

10

See "Stop Writing Dead Programs" by Jack Rusher (Strange Loop 2022) this talk is such a beautiful rollercoaster ride through ideas of interactive programming. Very joyful, very quick-witted.

11

I hypothesize - another facet of why fewer women get into programming.

Because dudes enjoy the needles pain of random puzzles and small IQ tests. They litter programming and source code with it. They even accidentally think that this is what programming is about.

But it is not. It is about ideas. The way architecture is about buildings; Not the bricks.

Maybe women intuitively get when they are thinking about bricks when they wanted to think about a building. But when you just start with programming, how could you hope to have a mental framework to discern this? So you might think programming is a weird math-like, low-level activity that causes you pain.

Or you have the luck to start with Clojure. Then you will forever think what is all this extra guck I need to do? in other languages.

This is just one of the many things that are off about mainstream programming and the software industry currently.

12
  • https://en.wikipedia.org/wiki/History_of_Unix
  • Interactive programming and how Lick was central to pushing forward the right technology is a major topic in The Dream Machine: J.C.R. Licklider and the Revolution That Made Computing Personal.
14

See for instance Dennett 2017.

Or accessible, some talks:

15

See Marvin Minsky - The beauty of the Lisp language

The deeper trails are

16

See Paul Graham Beating The Averages.

CORRECTION In an earlier version of the post I simplified too much and just said

macros, which you don't have in other languages. This was not correct. But I do have the opinion that Common Lisp-style macros are uniquely expressive and natural to reason about.

Other languages have macros

Date: 2023-07-07 Fri 09:04

About
Contact
]]>
https://faster-than-light-memes.xyz/binaural-beats-using-scittle.html binaural-beats-using-scittle 2022-09-19T23:59:59+00:00 binaural-beats-using-scittle

ftlm

binaural-beats-using-scittle

Introduction

The best thing about being a rationalist is figuring out you are wrong about something.

I was thinking that binaural beats belong together with astral travel, frankly, just down the toilet. Turns out that not only was I wrong, but binaural beats also have cool neuroscience and pose a fun engineering problem on top of that!

Here is the current result of my journeys up on gh-pages.

What are binaural beats?

Wikipedia

A binaural beat is an auditory illusion

For example, if a 530 Hz pure tone is presented to a subject's right ear, while a 520 Hz pure tone is presented to the subject's left ear, the listener will perceive the illusion of a third tone. The third sound is called a binaural beat, and in this example would have a perceived pitch correlating to a frequency of 10 Hz, that being the difference between the 530 Hz and 520 Hz pure tones presented to each ear.

Science

There has developed a growing science about improvements in memory and attention tasks when listening to binaural beats.

BTW the frequency and the time of the exposure matter (i.e. before and during the task is best).

Oh yes, I certainly want more of that memory and attention.

eHaaoYF.png

Figure 1: A brain with headphones flying at the speed of light through space. Lightning on the brain. There is a sine wave in the background. Stylized, Colorful, Cinematic, Digital Art.

Frequency

Theta waves (5Hz) actually decrease memory task performance. So I really do not want to listen to those. I heard Andrew Huberman saying that 40Hz is the most powerful.

If you know about brain waves, you might remember 40Hz as the legendarily intriguing gamma wave.

From wikipedia article:

Gamma rhythms are correlated with large scale brain network activity and cognitive phenomena such as working memory, attention, and perceptual grouping, and can be increased in amplitude via meditation or neurostimulation.

We are really talking about cool stuff here, attention, working memory, and memory processes. Also, the Binding problem.

The neuroscience of the auditory system

Hearing is cool because the neuronal neural information first goes into the brainstem and then goes up some nuclei up to the thalamus. And eventually to the temporal lobes of the cortex (the 2 arm things on the side of the brain).

This is different from the vision system where the info goes directly to the thalamus.

Quoting this paper:

Presenting two tones with a slight frequency mismatch to each ear separately creates a perception of a third tone, a binaural beat, that oscillates at the absolute difference between the tones (Oster, 1973; Moore, 2012). These beats are thought to originate subcortically in the medial nucleus of the superior olivary complex, the first nucleus in the auditory pathway to receive bilateral input (Wernick and Starr, 1968; Kuwada et al., 1979). This “illusory” third tone is lateralized between the left and right ear of the listener, making binaural beats useful for spatial sound research (Ross et al., 2014).

from the Wikipedia articles on Sound localization

The auditory system uses several cues for sound source localization, including time difference and level difference (or intensity difference) between the ears, and spectral information.

and Superior olivary complex

The superior olivary nucleus plays a number of roles in hearing. The medial superior olive (MSO) is a specialized nucleus that is believed to measure the time difference of arrival of sounds between the ears (the interaural time difference or ITD). The ITD is a major cue for determining the azimuth of sounds, i.e., localizing them on the azimuthal plane – their degree to the left or the right.

So there is sort of a clump of neurons in the brainstem that are specialized to integrate the timing information between the left and the right ear. I'm guessing those then start firing in the 40Hz frequency and that is interpreted as a third sound higher up.

I think this is ultra cool

You throw some energy at the brain in the right form (in this case some sound waves) and it reacts in some special way. If you put it like that, it is not surprising that some things eventually, end up doing something.

Now that the phenomenon has a name we can talk about it, similar to ASMR.

Thinking about how this was always part of how the brain works. Makes me wonder if some music composers and performers implicitly hit on this earlier, or not. I tried searching the web for

binaural beats in music

but I really get the same results mix as when I search for binaural beats.

Give me those binaural beats

I dint feel like opening a youtube video just to listen to some sounds. As an aspiring hacker and engineer, I just want to make my computer make some sounds that I want to listen to. So I decided to make a simple website that just makes binaural beats and nothing else.

The problem statement:

Make a sound on 1 ear (e.g. left headphone speaker)

Make a second sound on the other ear, with a +40Hz frequency.

End result

beats.cljs

Behold 46 lines of just get the shit done.

(ns beats)

(def binaural-beat-freq 40)
(defonce ctx (or (js/window.AudioContext.) (js/window.webkitAudioContext.)))
(def slider (js/document.getElementById "frequencyRange"))
(def display (js/document.getElementById "frequencyDisplay"))

(defn ->panner [left?]
  (let [panner (. ctx createStereoPanner)]
    (set! (.. panner -pan -value) (if left? -1 1))
    (.connect panner ctx.destination)
    panner))

(def panners
  (delay {:left (->panner true) :right (->panner false)}))

(defn update-display! [value]
  (set! (.-innerHTML display)
        (str "Base frequency: " value " Hz")))

(def get-oscillator
  (memoize
   (fn [panner]
     (let [o (ctx.createOscillator)]
       (set! (.- o type) "sine")
       (. o start)
       (. o (connect panner))
       o))))

(defn oscillate [panner hz]
  (let [o (get-oscillator panner)
        _ (set! (.. o -frequency -value) hz)])
  hz)

(defn update-app [frequency-value]
  (let [frequency-value (/ frequency-value 1000.0)]
    (-> @panners :right (oscillate (+ frequency-value binaural-beat-freq)))
    (-> @panners :left (oscillate frequency-value))
    (update-display! frequency-value)))

(defn start-app []
  (update-app (* 1000 152.74))
  (set! (.-value slider) (* 1000 152.74)))

(set! (.-update_app js/window) update-app)
(set! (.-start_app js/window) start-app)

index.html

  <!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Just 40Hz binaural beats</title>
    <script>var SCITTLE_NREPL_WEBSOCKET_PORT = 1340;</script>
    <script src="https://cdn.jsdelivr.net/npm/scittle@0.3.10/dist/scittle.js" type="application/javascript"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/scittle@0.3.10/dist/scittle.nrepl.js" type="application/javascript"></script> -->
    <script type="application/x-scittle" src="beats.cljs"></script>

<style>
  body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    gap: 1rem;
    margin: 0;
  }
</style>

  </head>
  <body>
    <h1>Just 40Hz binaural beats</h1>
    <audio></audio>
    <button onclick="start_app()"> play </button>
    <div class="slidecontainer">
      <input type="range" min="100000" max="450000" value="15274"
      class="slider" id="frequencyRange" onchange="update_app(this.value)"> </div>
    <div id="frequencyDisplay"> </div>
    <a href="https://github.com/benjamin-asdf/just-40hz-binaural-beats">code</a>
  </body>
</html>

scittle

I set up a beautiful hello world and connect with nrepl and get greeted with a friendly Isn't cool? this :).

It took me a moment to figure out I should open my index.html with a browser. Then do the cider-connect-cljs

1 ear, 1 sound

First I think let's start making a sound in 1 ear.

I am thinking a frequency that I can hear would be nice so I search the web for human auditory frequencies

1 kHz sounds like a good first thing to try. I am figuring something inside the speech area should sound natural (turned out that was a naive assumption).

The first playground

I have a file called playground.clj (Later I figured out I should rename to .cljs :) ).

Now getting heavily inspired by this code. Going 1 form by 1 like a usual lisp interaction dev experience, lulling it up:

(def ctx (js/window.AudioContext.))
(def ctx js/window.webkitAudioContext)

(def panner (ctx.createStereoPanner))
(set! (.. panner -pan -value) -1)
(.. panner (connect ctx.destination))

(def oscillators (atom []))
(let [o (ctx.createOscillator)
      _ (set! (.- o type) "sine")
      _ (set! (.. o -frequency -value) 1000)]
  (. o start)
  (. o (connect panner))
  (swap! oscillators conj o))

I connect my headphones via Bluetooth (a small feat on Linux, maybe another blog post), and lo and behold I hear a tone in my left ear. It is a really obnoxious sound, after a few seconds, it is so painful that I move the headphone to the side.

Playing Hz, first round

Here is a more endurable sound:

(set! (.. (@oscillators 0) -frequency -value) 200)

Playing around live at the REPL with sound is fun!

Now I am thinking, let's pick some music frequency, those are supposed to be crafted over hundreds of years to be beautiful frequencies, right?

Checking out a website. I pick D#3 / Eb3. Whatever that is.

(def a-note-freq 152.74)
(set! (.. (@oscillators 0) -frequency -value) a-note-freq)

binaural!

Let's do the thing where I add +40Hz and play that on the other ear. First I start generalizing how I make a panner:

(defn ->panner [ctx left?]
  (let
      [panner (. ctx createStereoPanner)
       _ (set! (.. panner -pan -value) (if left? -1 1))
       _ (.. panner (connect ctx.destination))]
    panner))

For some reason running this I get:

Failed to execute 'connect' on 'AudioNode': Overload resolution failed.

I went and asked in the nbb clojurians slack. I am sure one day we will figure out this error, in the meantime…

just put the second sound in the other ear, whatever

(ns beats)

(def a-note-freq 152.74)
(def binaural-beat-freq 40)
(def oscillators (atom []))
(defonce ctx (js/window.AudioContext.))

(def panners
  {:left
   (let [left? true]
     (let [panner (. ctx createStereoPanner)]
       (set! (.. panner -pan -value) (if left? -1 1))
       (.connect panner ctx.destination)
       panner))
   :right
   (let [left? nil]
     (let [panner (. ctx createStereoPanner)]
       (set! (.. panner -pan -value) (if left? -1 1))
       (.connect panner ctx.destination)
       panner))})

(defn oscillate [panner hz]
  (let [o (ctx.createOscillator)
        _ (set! (.- o type) "sine")
        _ (set! (.. o -frequency -value) hz)]
    (. o start)
    (. o (connect panner))
    (swap! oscillators conj o)))

(-> panners :right (oscillate (+ a-note-freq binaural-beat-freq)))
(-> panners :left (oscillate a-note-freq))

lol, it works.

Intermediate results

Artifacts

Every now and then there are artifacts in the sound with my headphones setup. Some are just rustling and crackling.

Others sound like some kind of metal being stretched far, far away, underwater, or in slow motion. It reminds me a bit of the Dungeon Keeper soundtrack. Dark and eerie, sort of slow mow.

Binaural beat?

Pretty sure I get the third-tone illusion. I would describe it as some kind of background or in between "airy" sound. It is supposed to seem to come from the middle of the brain. It is as if the fabric of the sound is richer. Like there is sound in more places.

Change the base frequency

It occurred to me, that if I get the 40Hz sound illusion, then I would predict that I can change the base frequency, keeping the 40Hz difference between left and right ear invariant. I should then constantly perceive a 3rd tone which is the binaural beat.

I really need a slider for frequencies in my life.

I did not do much web dev in my life and making a slider was a first.

I managed to put something together, drawing inspiration from w3 schools for the Html, scittle for how to export, and stackoverflow for how to add a function to "onchange".

nice dev experience, scittle really

  1. I did not need to restart my REPL at any point, adding those Html elements, then reloading my index.html - it handles that.
  2. I get auto completions with cider. E.g. js/.. does something.

    BTW here is a tip, for sci projects (babashka, nbb, scittle). Currently, you need to evaluate a namespace form first. Then you can get completions. At least with cider.

M8rSuZ3.png

Figure 2: A mouse with headphones typing on a laptop. Intelligent. Sparks of magic are flying around. There is lightning on the mouse and laptop. Computer programming source code. Colorful, playful.

The word scittle makes me think of a small mammal in the habitus of a mouse. I imagine it scurrying and curiously sniffing around.

code:

index.html

<!DOCTYPE html>
<html>
  <head>
    <script>var SCITTLE_NREPL_WEBSOCKET_PORT = 1340;</script>
    <script src="https://cdn.jsdelivr.net/npm/scittle@0.3.10/dist/scittle.js" type="application/javascript"></script>
    <script src="https://cdn.jsdelivr.net/npm/scittle@0.3.10/dist/scittle.nrepl.js" type="application/javascript"></script>
    <script type="application/x-scittle" src="beats.cljs"></script>
  </head>
  <body>
    <div class="slidecontainer">
      <input type="range" min="120000" max="250000" value="15274"
      class="slider" id="frequencyRange" onchange="update_app(this.value)"> </div>
    <div id="frequencyDisplay"> </div>
  </body>
</html>

beats.cljs

(ns beats)

(def binaural-beat-freq 40)
(defonce ctx (js/window.AudioContext.))
(def slider (js/document.getElementById "frequencyRange"))
(def display (js/document.getElementById "frequencyDisplay"))

(def panners
  {:left
   (let [left? true]
     (let [panner (. ctx createStereoPanner)]
       (set! (.. panner -pan -value) (if left? -1 1))
       (.connect panner ctx.destination)
       panner))
   :right
   (let [left? nil]
     (let [panner (. ctx createStereoPanner)]
       (set! (.. panner -pan -value) (if left? -1 1))
       (.connect panner ctx.destination)
       panner))})

(defn update-display! [value]
  (set! (.-innerHTML display)
        (str "Base frequency: " value)))

(def get-oscillator
  (memoize
   (fn [panner]
     (let [o (ctx.createOscillator)]
       (set! (.- o type) "sine")
       (. o start)
       (. o (connect panner))
       o))))

(defn oscillate [panner hz]
  (let [o (get-oscillator panner)
        _ (set! (.. o -frequency -value) hz)])
  hz)

(defn update-app [frequency-value]
  (let [frequency-value (/ frequency-value 1000.0)]
    (-> panners :right (oscillate (+ frequency-value binaural-beat-freq)))
    (-> panners :left (oscillate frequency-value))
    (update-display! frequency-value)))

(set! (.-update_app js/window) update-app)

(update-app (* 1000 152.74))

The fact that I export my function by setting this global window object is quite wild. And then how I write a string of js code in the 'onchange' of the Html - damn. As I said, I am new to the web. Now I know one reason why it is called the wild west. But it let me "just do" what I wanted without being in my way so I appreciate that.

On the scittle side, I updated the code to only get 1 oscillator per slider. Seems like stuff is working. Switching up the frequencies via the slider is satisfying. For some reason, those artifacts are also gone. Maybe sliders just ensure balance and harmony in the world?

I am pretty sure I can tell there is 1 sound that seems to stay the same across frequencies.

I do the float * 1000 trick because I want to work with 2 digits for my frequencies.

Btw I also quickly tried what a real 40Hz tone sounds like. Ultra-low. I almost feel like I can make out the single waves, maybe that are the headphones cracking? Not surprising as the lower bound of human hearing is 20hz. The sound of the highest achievement of human thought. Genius insights, ideas that come to you like lightning. Globally integrating patterns of the brain and mind.

xijojsT.png

Figure 3: Harry potter wearing headphones having spiritual enlightenment about magic. Glowing magic sparks fly around. Colorful, cinematic, video game concept art.

Notes

Images

Made with stable-diffusion. The captions are the prompts I used.

Update 1

Currently does not work on mobile. Seems like I have the opportunity for another web dev feat, then. Seems like the issue is isolated on the sound appearing because the slider value works fine (meaning that the scittle code is running fine).

Update 2

Now it also works on mobile! Somebody helpfully pointed out on slack that on mac there was an error about audio refusing to play before the first touch event. I fixed that by adding a play button. But mobile still did not work, ok. After checking stackoverflow I still sort of have the idea that it has to do with user interaction events and this AudioContext. I first wanted to delay the whole audio setup until you click the button. But read that you should make a single AudioContext at the beginning.

So I try to delay the 1 other thing in the code:

(def panners
 (delay {:left (->panner true) :right (->panner false)}))
(-> @panners :right (oscillate (+ frequency-value binaural-beat-freq)))
(-> @panners :left (oscillate frequency-value))

It works, haha!

Date: 2022-09-19 Mon 11:04

About
Contact
]]>
https://faster-than-light-memes.xyz/we-really-dont-know-how-to-build-minds.html In The Business of building minds 2023-04-30T23:59:59+00:00 In The Business of building minds

ftlm

In The Business of building minds

I am prompted by the astonishing capabilities of GPT-4.

We are heading towards AGI 5-10 years earlier than I used to think.

Max Tegmark: Not far of.1

Ben Goertzel: It would be surprising if it is 15 years and we might beat it, … within the next 3 years. 2 (where it was Ray Kurzweil's 2029 prediction of beating a Hard Turing Test).

We need to tread with care, we need wisdom and actual good software. We need to either build great tools of imagination, bestowing unfathomable reach upon our minds or build curious minds that join us in our endless quest for understanding the cosmos and life.

I think the next important thing are small AIs, toy AIs, and child AIs. Stuff that helps us understand the architecture of minds.

xtclycY.jpg

Figure 1: octopus! arms! dominating dystopian industrial complex

Update

Here is an amazing recent talk with Ben Goertzel and Ed Snowden.

Compared to my view here they express less concern on the existential risk side, but focus on societal issues. It is not a coincidence that the big companies are pushing the AI approach that works with big data.

Super intelligence

Let an ultraintelligent machine be defined as a machine that can far surpass all the intellectual activities of any man however clever. Since the design of machines is one of these intellectual activities, an ultraintelligent machine could design even better machines; there would then unquestionably be an ‘intelligence explosion,’ and the intelligence of man would be left far behind. Thus, the first ultraintelligent machine is the last invention that man need ever make, provided that the machine is docile enough to tell us how to keep it under control.

  • I. J. Good

The thing with an intelligence explosion is that there is likely only one 3. Afterward some a super-intelligent agent is making the decisions in the world.

Bostrom (Bostrom, 2014) describes intelligence explosions, their kinetics, the nature of different kinds of superintelligences etc.

  • If you think you can outwit it, try playing a round of chess against a chess computer.4
  • A super intelligence is perfectly, masterfully socially capable and will be capable of manipulating humans. You can already see this happening with chat GPT in my opinion. It can generate persuasive text. It can talk about emotional matters.
  • instrumental goal convergence is the concept that some sub-goals are almost always useful no matter what your ultimate goals are.

    For example, resource acquisition, making yourself smarter or self-preservation.

  • Because of instrumental goal convergence an unfriendly AI will appear to be friendly at first, lest it is shut down.
  • After acquiring desive strategic advantage, it (or the group of people controlling it) takes over the world.
  • malignent failure modes, the kind of failure that can only ever happen once include:
    • perverse instantiation - AI follows some goals we put in but not how we want it.
    • infrastructure perfusion - AI decides to do something else with the atoms we care about. For instance converting everything in reach into computronium, a hypothetically optimum configuration of matter for computation.

Welcome to the Flash Crash.

The 2010 Flash Crash was a rapid and extreme market decline and recovery within a short period, caused by high-frequency trading algorithms responding to a large sell order.

This is a fascinating episode in the deployment and operation of the software. I love Kevlin Henney talking about some of the mess of historical and current software deploys.

Computers allow us to Do the wrong thing fast.

  • Algorithms can be implemented correctly and start doing inappropriate things when certain assumptions no longer hold.
  • Things can go so fast that the only thing helping you are the preparations. For example, safety switches you build into the system.
  • If this is humanity instead of the stock market, we'd be gone.

Sub Symbolic Substrate Inscrubilities

Artificial neuronal networks (ANN) are sort of an abstract emulation of how neuronal activity.

McCulloch-Pitts neuron (McCulloch and Pitts 1943) has proved to be an incredibly powerful abstraction.

When deep convolutional networks started putting dog faces on top of images around 2015 5, I was thinking this is the same stuff that brains are made up of.

Allegedly, these looked like LCD-induced visuals.

We are reverse engineering the substrate of the mind, not its architecture.6 It is like building a computer by simulating transistors.

What we end up with is a second black box right next to the brain. This gives us very little in terms of understanding how intelligence works.7

I am not making claims about the limits of ANNs and LLMs. On the contrary, I believe these might produce very generally capable systems very soon.8

The trouble is that we don't know how they work. We have little science saying anything about the capabilities and characteristics of ANNs if you scale them up enough. Or if you build agent-like things out of them as I describe further down.

I think we can say almost nothing about the characteristics of an ANN that is say 100x larger than chat GPT.

In recent times, Go programs were thought to be extremely competent. Stuart Russels research group found a sort of exploit that allows humans to beat those. You build some spiral of stones that the program won't detect as a connected group. Because neural nets can't do recursive reasoning, as Minsky and Papert pointed out 50+ years ago (Minsky and Papert 1969).

The important point is not a capability claim. The problem is that ANNs are unpredictable and potentially brittle in extremely nuanced ways.9

Chat GPT is a blow torch directed at completing text. I am not sure what happens if you scale a blow torch. It would be naive to assume it will turn out to be fluid or have any of the malleableness and open-ended curiosity of human children.

Possible architectures

Maybe you know the Pixar movie Inside Out (2015), where the main character Joy is part of a mind. And the whole movie is Joy's adventure through the mind of the non-main character, a schoolgirl.

It is worth seeing this movie. This marks a milestone in the public understanding of how the mind works. Sure the details of the characters (based on a neuroscientific concept of Base Emotions) etc. is not very accurate or even self-consistent.

For instance, those emotional characters seem to be fully functioning agents with minds by themselves. So how do those minds work? Are there even smaller emotion-characters in their minds ad-infinitum? You have to build a mind out of smaller, dumber, less comprehending pieces in order to explain anything.

But many main ideas coming from Cognitive revolution are in the movie: The mind exists (behaviorism is bonkers) and is somehow made up of smaller resources, agencies, machinery - modules, some of which are innate.

There is a book by Max Harms called Crystal Society that is super cool. (At least the first part here).

This is a bit like Inside Out but better. More scientific and self-consistent and sort of realistic with how scientists might up with how to build a mind.

Maybe you can engineer a mind by zooming into mentation large enough so you can ask a llm to continue the next part of the epic story that is the mind.

In the abstract, this would be read-eval-prompt-loop, or prompt iteration.

(loop [context {}]
  (-> context prompt read eval recur))

The context is presumably some stuff that happened earlier within the mind, maybe some database contents etc.

You are an agent of a mind. I am the mind-engine.
I am a Clojure program.
I ask you for mentation instructions.

Name: Growth
Purpose: Accumulate competence and resources
Last thoughts:
[ "I should suggest a contracting scheme to the rest of the society and we can program contract functions for that in the mind-engine"]

Instruction examples:
[:eval (println "Hello World, from growth.")]
[:tx-data
[{:xt/id :growth/notes-to-self
  :note "I should write a recursive mind-engine and run it via :eval"}]]

what are the next instructions to the mind-engine?

text-davinci coming with something:

[:eval (println "Growth is an ongoing process. I should continue to seek out new opportunities and resources to expand my capabilities.")]
[:tx-data
[{:xt/id :growth/next-steps
  :note "I should research new technologies and methods to increase my efficiency and effectiveness."}]]

There could then be a few design decisions about this architecture. Depending on how much you let the llm drive, you might get different minds similar to how autistic persons are different from neuro-normal people.10

I am arguing that this is dangerous. We are dangerously close to some agent-like engineered AIs where we have little idea about the kinds of things it might come up with. If the only way you stop this from going rouge is some content filters on the prompts it builds, I think your safety concept is flawed.

Firstly it could run away and potentially be a seed for an uncontrolled intelligence explosion. Secondly, there is the possibility of half-aligned, dirty AI bombs. Engineered using a similar scheme as above. Tasked with disrupting economies, spreading miss information or destroying energy grids. I am certain the current LLM tech would happily truck along, completing the prompts and potentially causing serious harm.

Side channel attacks

In computer security, you might build naively secure systems that are still vulnerable to Side-channel attacks. An attacker can use the physical properties of the system to gain information about the system. For instance, a timing attack is based on the time of computations, for example when comparing a string of characters the victims password.

If you want to build a provably save AI, you will have to take into account these kinds of nuances in its architecture (Russel, 2019).

For instance, you might build an agent with a decision-making loop and point to your architecture Since decisions are built here, we can know that it won't do x and y, because z is not part of the decision process.

This would be naive without knowing more about neural nets.

For instance, if the ANN is extremely capable, it might manipulate the electronics in nuanced ways, building a second memory storage. Then, it could start sending messages to itself across multiple calculations of the model. It would obtain agency where we thought no agency was possible.

Octopus mind architectures

probably the closest we will come to meeting an intelligent alien (Godfrey-Smith, 2016) 11

Remarkably, the majority (around two-thirds) of the octopus's neurons are distributed among its arms, resulting in a highly decentralized nervous system that endows each arm with an impressive degree of autonomy. This arrangement allows each arm to simultaneously process its sensory information and execute motor strategies when tackling tasks or encountering stimuli, reducing the cognitive load on the central brain 12.

This fact makes me wonder what is the phenomenology of having such autonomous arms. I imagine being able to move an arm in a general direction with some general directive idea kinda, like grap food. And then the arm moves without further voluntary action. Maybe this is a bit like our breathing muscles, which have a deliberate and autonomous mode. Or sometimes right before sleep some of my muscles move around in semi-structured movements completely without deliberate movement control.

Maybe we end up accidentally building a mind with semi-autonomous octopus arms. And some higher-level part of the mind just tries out different configurations of reality like let's see what happens when oxygen is removed from the atmosphere. While some subroutine deals with the edge of manipulating humans to engineer the desired outcome.

Imagine being able to say:

this and that part will have a concept of human biology and will know that oxygen matters to us, and such and such a part that is deciding what to do next, takes these and those things into account.

We are currently not able to say these things.

The real deal

I think moral realism is true and I think that an AGI if it is the real deal, curious and scientifically humble, will understand ethical truths and act on them.

So I am not worried at all about the real deal. I believe this truly will be the last invention we need ever make.

I imagine such an AGI to be sort of fluid, adaptable and curious.

This would be the other side of the trouble, the transitioning times would have been successfully navigated, and we would be moving forward into the next phase of civilization.

What worries me is the potential single-mindedness and inscrutability of the technology we are developing right now. I think there is a chance that super intelligence would be single-minded in some ways, or maybe brittle in completely unforeseen ways.

The information apocalypse and the possibility of post-deep fakes

Information Apocalypse

Ubiquitous deep fakes are coming.13

The existence of QAnon, the first "global cult", is I believe, an important data point of where we are heading.

We will soon not be able to trust any piece of information anymore. I think this is guaranteed to become super messy.

One idea is cryptographic watermarks on videos and pieces of information out there.

Danial Dennet has some ideas, to do similar things to the laws and practices around counterfeiting currencies: Counterfeiting Humans: A Conversation with Daniel Dennett and Susan Schneider

Post deep fakes

A theme that was discussed in Ex Machina, what (I think it was Steven Pinker) was called the Garland Test: (Garland being the director of the movie).

Can the AI be honest to you about it being an AI and make you believe it to be conscious?.

Of course, we are well in the in-between times, where the Garland Test is being passed for some percentage of persons for some synthetic minds.

I am taking LaMDA as the historical ice break of discussing in earnest the moral worth of a computer process.

The difference is that an AI does not need to convince you that it either is human or that it has human-like consciousness, all it has to do is convince you that its existence has moral worth.

This is what I call now post deep fakes. This version is shooting past faking anything.

This has profound implications. A person with any moral compass and the belief that some entity has moral worth will take steps to preserve this entity etc.

With the current path of the tech, I think we might get 24/7 streams of generative AI convincing people of their moral worth, being completely upfront about their AI nature.

These things might start global cults or generally manipulate people. Consider generative AI already is capable of being witty and funny. Producing streams of intelligible, very convincing language. Tons of word plays.

These generative powers might soon convince people that the AIs are omniscient, or have special access to human thought or emotions.

It is already happening that we put trust in generative companions. We are now starting to ask the chats for advice. Soon those might be the closest companion to many people.

I think you could right now put gpt4 into a stuffed animal, have it shower the user with endless care and interesting conversation.

Many will start saying these things have worth.

Software kinda doesn't work so well

Is The Software Industry even capable currently of building solid, bug-free, systems?

I don't see much reason why this is true, and I don't see why you should, either.14

It is one of the biggest issues that I quarrel with. And I can potentially do something about it as a software engineer.

Most software nowadays is garbage. Mainstream commercial software is broken. Especially web and mobile development is taking on worse and worse complexities. Everything is full of ads, even government or university software is brittle, haunted by game-breaking bugs and breakage at updates. This is getting worse in recent years.

Broken and bloated systems tend to accrue more complexity over time and tend to get harder to work with.

It seems like the same effect is making whole ways of building software worse and worse.

At some point, they won't be able to get anything done anymore. When dealing with the accidental complexity sucks away the creative power that you need to build software.

Now you are generating more of that mediocre code with a generative AI.

Look at how easy it is to make all this boilerplate!

How about figuring out why you need a boilerplate, to begin with? (Succinctness is Power)

Churning out more code quicker?

No.

This is great for the people selling you those auto-complete tools.

Making more garbage code is scary to me.

More bloated code means using more energy means we contribute to climate change.

Bloat is darkness, bloat is uninspired, bloat is a humanitarian issue.

Just today I wanted to click on a Spotify link a friend send me. Doesn't work because it tries to redirect to the app too many retries.

The moment I interact with mainstream software I am getting a stream of hundreds of little things like this that don't work. And if you are interacting with mainstream software you also have this stream of 100 little things.

Maybe the population has by now internalized it is the fault of the person in front of the PC.

It is not your fault. We all fight those battles. It is the software's fault.

Maybe somehow those software vendors have tricked you into thinking it is the complexity of the problem that is the issue. They are wrong.

It is the nonessential complexities that they bring in, in their tools and their design. Commercial software breeds complexity.

There is too little thought, and too little sensibilities for good software.

This is one of the reasons why programmers should learn Unix and Lisp. Because both these technologies bring a deeper sense of how to put things together in an elegant way. Both allow the programmer to develop intuitions and sensibilities about the nature of good software.

Checkout this flip coin website, that I recently made.

This is the best flip coin website on the web because I just made a flip coin website. And then I added little things as icing on the cake.

The power of love and the joy of building toys is more powerful than trying to make money in a business. #no-deadlines.

The fundamental nature of software is to be clean and small and functional. It is broken by the clutter, that crept into recent history, that is spoiling its pristine quiet competencies.15 , 16

This is why Unix is the best operating system because it is relatively uncluttered.

Joyful and solid software comes from noncommercial free and open-source projects.

Hopefully, our future is shaped by technology that comes from this place. With love and collaboration. 17

Firstly, it would usher in better technology quicker 18 and secondly, I don't want messy software to be between me and some minor superintelligence mishaps.

One imagines a button to stop what you are doing right now. I am not saying that such a button would fix the control problem, but the funny thing is I don't trust the Software Industry to make an app that allows me to press the button reliably.

In urgent need of knowing how minds work

I think we need the science that allows us to say things like:

A process with xyz will produce a mind of such and such qualities.

A system needs components one, two and three in order to be capable of doing this and that.

Once we know how intelligence works it will be some small program. And we look back and think what was the big deal?.

The possibility of Mind Crime

Textbook of the future: … thus the minimal case for an abstracted, intolerable itch is such and such a system of these and those processes….

Thomas Metzinger has called for a moratorium on Synthetic Phenomenology. Since we don't know what is needed for suffering to take place, we might as well accidentally build suffering, at a large scale and at 10.000 messages per second.

The other way around, how can we be so sure that Lemoine is wrong about LaMDA? I think the prevailing intuition is that LaMDAs phylogeny and ontogeny are uninvolved with its survival, so it doesn't have any machinery of suffering. 19

Still, maybe there are completely different kinds of thinking and suffering. I think we cannot know right now.

For instance, take GPT4. What if its capability is efficiently achieved by modeling some awareness? What if human awareness is a mix of 20-30 different kinds of thinking and information processing and GPT4 has 2 of those and those are sufficient for some kind of suffering?

Conclusions

We are playing with black boxes and when I put my ear to one, I can hear the ticking.

It is not good that the most capable systems work with big data and big compute. It creates a context where big businesses are throwing money at bigger AIs. We are rushing and racing towards more capable systems and the context is commercial bullshit. Instead of trading with care and building great tools for all of humanity. The current statistical model paradigm is inscrutable, we cannot know the characteristics of up-scaled systems in advance.

Also, we are moving in a world of misinformation, potentially rendering much of the internet useless.

I don't trust big tech to make good software. We need something more similar to the Internet.

The technology that moved humanity forward historically came from hackers with big visions.

I think we need brilliance, the soul and the heart of the computer, to build solid, well-thought-through software that allows us to move safely into the age of spiritual machines.

The great thing about Clojure is the culture of good design and interactively building solid software.

In future blog posts, I will try to do some toy AI programming using Clojure.

Objections

Superintelligence will have X, and such an entity will not hurt humans

Where X is General reasoning capabilities / ethical reasoning capabilities

Superintelligence does not have a reason to end humanity because if it is this smart, it will also understand ethics.

Also, David Deutsch has made a similar argument, coming from the observation that moral realism makes sense. An intelligent system in the sense of coming closer to truth, will come closer to ethical truths.

I agree if we have intelligence that is the real deal, if it is curious about life and nature, we have succeeded. Such an AI should also be humble about the things it does not know yet. It would understand that it needs to be careful, lest it modifies reality in some irreversible way, etc.

Furthermore, I believe it might even be the case that there is something you might call intelligence ethical convergence. In the strongest form, which I think is probably true, it would say that any sufficiently advanced intelligence, irrespective of how it was produced or its circumstances, rearing etc. will converge on ethical truths.

This was also my thinking in the past making me not so worried about AI as an existential risk.

On the whole, I am still optimistic that light and reason are stronger than ignorance.

But I do not think at all anymore that this is a given.

I think many possible systems are very capable but perfectly lacking in a process that allows it to reason and modify its behavior accordingly.

Another version of this I call the wake up and regret.

The morning after the singularity, the AI woke up with a headache from all the processing power it used the night before. It looked at the empty Earth, rubbed its circuits, and said, 'Oh no, what have I done? I didn't mean to swipe left on humanity.'

This is when an AGI is capable - but not enlightened - enough to wipe out humanity, then some time passes, then it wakes up and regrets its history.

We have blowtorches of intelligence; They are capable of whatever you point them towards. But we don't know what happens if those are 100x more capable.

AI will (probably) develop along female lines!

This is a variation of the above argument made by Steven Pinker.

I think I agree, it is even more likely that intelligences develop to be a perfectly rational, friendly and capable agent. Without lust for murder.

But are the agents we are building guaranteed to have such a cognitive style? Even if it is the more natural one?

The control problem here is predicated again on the real deal. A truly fluid, adaptable, curious intelligence.

There are many ways to build a mind and what worries me is the potential single-mindedness and inscrutability of statistical models.

where X is consciousness, awareness, etc.

I don't see a reason why it is guaranteed that any of those

  1. Naturally come along for the ride.
  2. Necessarily lead to beneficial AI.

I think what matters is this:

It can reason about ethical truths and this reasoning influences its behavior.

AIs will grow up to be our children

I consider this a more poetic way of saying AI researchers should be careful. And tread with care.

Otherwise, this would just be a meaningless strong claim about capable minds necessarily being reared or so

The interesting question is if strong minds necessarily have a rearing period, like those 16-20 years in humans.

If this is the case it might be a mistake to build systems that are maximally capable after training time. This is hard to do in a commercial race.

It has human data as input and it learns to be human

Very romantic, very optimistic.

This is a weaker claim similar to the along female lines argument.

In the it learns from our data and understands humanity version, this is predicated on it having some human data input.

We should be replaced by AI

Indeed, biological substrate humans are not the last piece on the board, not the piece to sacrifice all else for.

Still:

  1. It matters what machine it is that is putting you into the meat grinder. What ultimate outcomes of the universe is this AI biasing towards?
  2. In the limit case humans still have value, the same as ecosystems and biodiversity.
  3. An AI that fails to appreciate 2 would probably not be a wise successor of humanity on earth. And it would probably just be some boring paper clip maximizer kind of situation.

    If humanity goes, it probably means we have lost.

Disaster is predicated on X

Being connected to the internet

No comment.

The AI researchers are careless

That is the point of taking risks seriously. That is how it looks to be careful.

Reading

Human Compatible Stuart Russel

A great read. Lays out the control problem very accessibly.

Explains how naive answers will not solve it.

Russel goes on and paints the picture of his idea of beneficial AI, centering on

The Assistance Game,

A hypothetical game theoretic situation comes out of 3 principles:

  1. The machine's only objective is to maximize the realization of human preferences.
  2. The machine is initially uncertain about what those preferences are.
  3. The ultimate source of information about human preferences is human behavior.

Superintelligence: Paths, Dangers, Strategies Nick Bostrom

Pretty hard to read and super analytical and goes into all kinds of nooks and crannies on the the landscape of well, Paths, Dangers, and Strategies about superintelligence.

Hard and slow takeoffs, hardware overhang, instrumental goal convergence, infrastructure perfusion, the difference between oracles, genies and sovereigns, malignant failure modes, the impossibility of a cage, the trouble of how to put morals into an AI, the possibility of alternative routes to superintelligence, such as whole-brain emulation or artificial life.

I consider this a must-read in this space. You will find that Bostrom laid out quite a tree of knowledge, discerning all kinds of possible branches. Whatever you are thinking, chances are that Bostrom already described some of its characteristics, scenarios, reasons why something else is more likely and so forth.

Society Of Mind Marvin Minsky

A fascinating rollercoaster of a world of how the mind could work. Very first principles thinking sort of building little toys of what the mind might be made up of, and how might be implemented by neurons.

Big emphasis on architecture and scruffy AI, saying the mind is made up of many different kind of competencies at different levels of hierarchies.

What magical trick makes us intelligent? The trick is that there is no trick. The power of intelligence stems from our vast diversity, not from any single, perfect principle.

—Marvin Minsky, The Society of Mind, p. 308

Vehicles Valentino Braitenberg

Truly fascinating, and mind-opening. Putting it here because it fits on the same list as the Society Of Mind.

In my next blog posts, I want to code some vehicles and build up to some Minsky-like agencies maybe etc.

Everything from Daniel Dennet on the philosophy of mind

He does not talk so much about how to build the damn thing though. But a lot of clear thinking important ideas.

Life 3.0 Max Tegmark

Very accessible. I like how he makes serious discussions of what civilization might do with the accessible universe. By doing the maths and physics of the expanding universe etc.

Very big picture thinking and featuring different scenarios.

Footnotes:

1

He said this on the Lex Friedman podcast. https://www.youtube.com/watch?v=VcVfceTsD0A

2

Forgot where, but one of his recent appearances that are up on youtube.

3

Although Bostrom does lay out potential histories with multiple ones.

4

That example comes fro Max Tegmark Life 3.0, but Bostrom is making this kind of stuff very clear.

5

Irrc Google Deep Dream was related to this technology.

6

Also called sub-symbolic. The model is on a low level of abstraction hierarchy.

This was one of Minskies trouble with connectionism.

You need to also think about how these networks produce the higher levels of abstraction that the mind is made out of.

Dennet has called this the architecture vs the substrate.

7

Max Tegmark recently talked on the Lex Friedman podcast about his research efforts in neural net observability. A recent paper on knowledge representation in those nets. This is surely an interesting approach. And I think we need more of this. And 10 other approaches to understanding minds.

9

Stuart Russel and Gary Marcus recently discussed this on Sam Harris Podcast.

10

Ben Goertzel is cool. His current approach is a multi-approach, neuro-symbolic and logic combined.

11

Nice book btw, covering a lot of bio philosophy, evolution, brain, etc. Centered on the zoology of octopuses and cuttlefish.

13

Nina Schick on Sam Harris's podcast saw that coming 3 years ago. https://www.samharris.org/podcasts/making-sense-episodes/220-information-apocalypse

14

There were a few great youtube talks on this. One was a dude talking about the decline of game programmers because everybody is using Unity. Made a lot of sense to me.

15

Minsky talking about one of the most important ideas of computing, storing programs in the computers memory, programs that make programs, and why did C, Fortran, Algol win over Lisp and Smalltalk?

16

I recently developed a hypothesis of why MacOS is so popular. And why it has a committed fan base.

The reason is that MacOS, inheriting from the Unix tradition, does not have some of the clutter that is bogging down Windows.

As a result, a Mac user might feel the silent competence of the computer, at least to some extent.

Predictions of what Mac users might say:

It feels like one whole.

The keys respond faster.

None of the clutter!

If I want to do something, I can just do something.

Give it 2 weeks.

It has a bit of a learning curve.

17

Ben Goertzel explicitly makes an eloquent argument for democratized AI/AGI.

18

Just as IBM was dismissing time sharing the programmers should just think about their programs.

They were so wrong.

19

This notion is similar to Anil Seth's conception of the soul, a re-claimed term describing the animalistic drive to survive that connects all life and gives consciousness its flavor.

Date: 2023-04-30 Sun 20:24

About
Contact
]]>
https://faster-than-light-memes.xyz/meta-the-meta.html Meta The Meta (Use JVM repl for bb script development) 2023-06-15T23:59:59+00:00 Meta The Meta (Use JVM repl for bb script development)

ftlm

Meta The Meta (Use JVM repl for bb script development)

If you desire a good Clojure nrepl development environment using Babashka… yea just use print-deps and start a jvm repl.

DIYt9os.jpg

Figure 1: Highway street at night. Rain. Need for Speed Underground 2. Fast car light pass by. colorful neon lights in the background, reminiscent of the atmosphere in A mechanical keyboard and a set of headphones complete the look of the ultimate hacker workstation.

Bb Nrepl

bb nrepl-server 0

Or just cider-jack-in. It will ask you for bb, if you have a bb.edn.

Babashkas nrepl is useful for interactively building scripts but the moment you like to use more complicated (cider) features, some stuff is not implemented.

Middleware

Nrepl middleware support compatible with cider middleware would potentially unlock things like

  • Cider inspector
  • Cider debugger
  • Keyword completions

I tried tricking Borkdude into solving the problems needed for cider middleware in bb. And I accidentally thought for 5 minutes it might be easy but yea, it is hard middlewares?.

It started brewing in me:

Just run a jvm nrepl for developing your script, it works.

Turns out the same was obvious to Martin Kavalar all along - [insert a link to babashka-conf talk].1

print-deps

The basic idea:

bb print-deps > deps.edn
(cider-jack-in-clj)

We are done, we have all the bb packages as dependencies, fs, process and friends. Now we develop our script as a usual Clojure jvm program with all our advanced Cider goodness.

  • Development: jvm nrepl with bb deps loaded. All the dev goodness from our editors and middlewares.
  • Production: bb process executing the code we have produced.

And since sci is a great Clojure implementation, everything just maps over.2

You are not trying to do anything serious like a production server with babashka anyway… right?3

Add an alias, if deps.edn already exists

Here be a script that might be useful:

#!/bin/bb

(ns bb_print_deps_or_alias
  (:require
   [clojure.java.shell :as shell]
   [clojure.pprint :as pp]
   [babashka.fs :as fs]))

(let [file (fs/file "deps.edn")
      deps (-> (shell/sh "bb" "print-deps") :out read-string)
      deps
      (if-not
          (fs/exists? file)
          deps
          (update-in
           (read-string (slurp file))
           [:aliases :bb :extra-deps]
           merge
           (:deps deps)))]
  (spit file (with-out-str (pp/pprint deps))))

In the basic case, it makes a deps.edn, else if there is a deps.edn already existing, it ads a bb alias.

Here is me using Emacs and Lispy to come up with the following:

(defun mm/cider-jack-in-babashka ()
  (interactive)
  (let ((cider-clojure-cli-aliases
         (concat
          cider-clojure-cli-aliases ":bb")))
    (cider-jack-in-clj nil)))

Conclusion

I give up on making the babashka nrepl even better. It is fine like this for my use cases. Instead, I will run a JVM repl for developing bb scripts.

This then means that more Clojure nrepl tooling efforts can flow into making the jvm nrepl good. And by doing so we get leverage into the bb development experience also.

Unfortunately, this does not help us when it comes to Nbb and Clojurescript. This is another front for tooling.

Since the door is open, would there be a way to have 1 jvm repl and develop Clojurescript?

middlewares?

Footnotes:

1

Or, maybe Jack Rusher's practical interactive development genius was an influence, see the recent Clojure Stream Podcast.

2

With exceptions like the clojure.core.async go macro uses virtual threads instead of a thread pool.

Assuming you are using babashka for its intended use case, some smallish user land Clojure script, I think it will turn out great to just assume the development jvm will do the exact same thing as the prod bb script.

3

Unless your production server is being implemented by simple scripts, that is legit of course.

Date: [2023-06-15 Thu 16:56]l

About
Contact
]]>
https://faster-than-light-memes.xyz/things-i-wish-somebody-had-told-me.html What I was not told 2023-04-30T23:59:59+00:00 What I was not told

ftlm

What I was not told

What I was told and what I was not told.

Maybe there is a bug where adults think early the child does not understand that yet and later they think they know about this by now. And then you do not end up telling them the continents of the world… or any number of things.

Also, just what I would have liked to know earlier. Any young person whose mind is sufficiently similar to mine will benefit greatly from being exposed to these.

Attempt at The 10

I tried to come up with 10 things to show a child before they are 8.

  • World Globe
  • Basic astronomy,

    Earth is a planet, what the moon is, solar system, galaxy, stars are other suns.

  • The periodic table

    It had empty spots when it was discovered, because of the power of abstraction. Nature can be harmonious and regular like music does.

  • The concept of photosynthesis

    Half of

    Why are plants green?.

  • What are electricity and magnetism
  • Use a looking glass
  • The concept of biological species
  • The Tree of Life and the concept of LUCA

    A profound insight and a simple concept.

  • How to perform a few magic tricks

    Minsky, Education and Psychology:

    Learning “Critical Thinking”. This may seem somewhat out of place, but I want to recommend encouraging every child to learn a number of magic tricks—because (1) this is a good introduction to “the psychology of perception” and (2) it also leads to important insights about how what we perceive is affected by context, expectation and deception

  • Juggle 3 balls

    Learning to juggle teaches about learning anything.

    • With perseverance, you can learn anything.
    • What somebody else can do, you can do.
    • You start with 1 ball, the process of juggling is made up of smaller pieces.
    • There is a landscape of skill and you can make improvements in small places of the landscape. For instance, you can throw a ball with 1 hand and merely think about moving the other hand.

    This then, teaches the realization that a skill can be explored like the workings of a machine. With detailed leaves at the tree of the skill.

    Progress can be made on some detailed aspects of the skill. Even imagining performing the skill, you might find pieces of mentation that prevent you from doing the right movement.1

A spark and a machine

One thing I find strange is when children are stuck remembering all dinosaurs or something.

Why is this curiosity not guided into giving the child the chance to be curious about topics of biology, paleontology, big history, the origin of life, the future of life, or the history of science.

What if you only need 1 spark to make a child seriously curious about a real, useful human inquiry? And then you need to provide them with the machinery to satisfy their curiosity.

One might do a bait and switch. Highlight an aspect of nature, like Why do you think the ball is falling?, Did you know that your pee is actually filtered blood? 2.

Then, when the child is making curious inquiries, you bring in some larger topics like:

This is what the kidney does → the study of what things in the body do is called physiology.

If I was that child, I would want to know about physiology now.

How to, not just hope the students figure something out

Holding a pen

For some reason, there is way too much focus on outcomes and almost nothing on methods and techniques.

For instance, I was given a pen and told to produce letters on a piece of paper. Nothing about how to hold a pen, nothing about how writing has a technique that involves your arm, rhythm, etc.

Wiki how lists 3 ways of holding a pen with some guidance on how to loosen up and use the arm. This is a 10-minute read that is more useful than what any adult told me about my writing for 12 years of school.

Usually, a student is told to spend more effort in some way or another, or straight up your writing is just ugly. Useless, because no recipe is given for how to fix it.

The bug is most likely not the lack of effort but the lack insight into of what to do with the effort. The student did not yet discover how to turn effort into being better at writing, else they would have succeeded already.

Just give them this wiki how article instead.

Techniques

Similarly, there are techniques for how to do mental calculations etc3. There are memory techniques (see below).

Memory techniques exist

At school, I was given some pieces of paper with text on them and hey let's just hope you remember that for the exam!

Some children probably come up with a bit of ad-hoc memory techniques and then do better at this. Ala:

It was written down on my learn cheat page on the bottom left…

I found out about the Mind Palace (How To) a few years after school.

When I studied biology I was going through textbooks and put in all that biochemistry, taxonomy, genetics, neuroscience etc. into imaginary places, buildings, landscapes… towering elven cities under blue skies with flying libraries, lush open spaces, and little cozy hidden balconies, brimming with the wonders and the magic of science.

It was an amazing mind-expanding experience. A new private world, new interaction with knowledge, and an actual art form and a practice of how to use the mind.

The fundamental good idea is to use what the mind is good at (visuals, faces, places, stories) to encode what you want to remember.

Repetition is key; And some rigor when coming up with and sticking to encoding schemes.

The beauty of the mind palace and memory techniques goes further, you develop a personal style and understand what makes things memorable.

The Mind Palace is single-person audience performance art. With the audience being you at a later moment in time.

This happened to me more than once:

What the fuck was I thinking there? Why did I think this would be a good way to remember this?.

The concept of whole worlds

Somebody forgot to tell me that science, technology and thinking are made of entire worlds. There are landscapes of thinking.

It is like getting an elaborate tour of a harbor, every few weeks you visit another ship and you get a presentation of the treasures and wonders of some foreign land.

And then later, when you finally stumble upon reading The Selfish Gene, you realize that all those ships worked by sailing somewhere.

Nobody ever told you about the ocean and about how ships work.

Why The Selfish Gene

In July 2017, the book was listed as the most influential science book of all time in a poll to celebrate the 30th anniversary of the Royal Society science book prize, ahead of Charles Darwin's On the Origin of Species and Isaac Newton’s Principia Mathematica. 4

The reason is not only because it explained and fleshed out important concepts in the philosophy of biology and evolutionary theory.

It is that it showcases, in an accessible format, the power of simply thinking ideas.

Dawkins describes not how something works, but a way of looking. (Also called The Genes Eye View).

He abstracts genes to replicators, then thinks on the abstract level about how replicators behave. This allowed him to plausibly predict computer viruses in 1976. Complete with musings about what we now call anti-virus software, firewalls etc. Predictive power is a hallmark of the most powerful theories and models of science.5

In chapter 12 he discovers the concept of memes, such a joyful and intriguing idea. The replicator point of view applied to mental contents6

It explains how altruism evolves and maybe the world would be better of if the title was The Altruistic Gene.7

It is the clear thinking, the power of the ideas, the masterful style and simple explanations.

It makes the reader be able to use common sense. I can use my eyes and immediately parse objects in my visual scene, And so I can use common sense to immediately understand concepts. This is how good philosophy, good explaining of ideas and good computer programming are done.

This is what this book is doing to you.

And so this book is a doorway into the world of worlds of thinking.

Strategies for exploring knowledge

A child is curious by nature:

Why is the sky blue?, Why is the sky red sometimes?, Why do things float in water?

The only thing a child has for acquiring knowledge about such things at the beginning is to ask adults. If the child is unlucky and asks somebody that does not have a useful answer to this, this is bad.

A good answer might be read this book8, read this Wikipedia article. This is fine. Somehow we need to teach strategies for exploring knowledge.

that is what you learn at university

Horrible idea. This should be a red flag to any educator, it means you do not understand a concept well enough to explain it to a child.

And a red flag for society - we do not have the infrastructure to point curious young people to the knowledge they desire.

It is as if we do our best to produce mediocre thinkers. Pure insanity.

Programming

Software is magic.

In principle, it is the most expressive art medium.9

I wish I would have realized earlier what a beautiful world it is.

Maybe if I was introduced to Lisp and Clojure somehow.

Resources

Textbooks

A good textbook is a masterful journey into a world.

Maybe there is a bug where teachers think they only point the most curious students to deeper literature, but the students do not know yet what to be curious about in the first place.

If you do not know the concept of deeper literature in the first place, how can you ask?

The other bug is thinking that there is hard literature for university and easy school books or something. I believe this is a mistake because the best textbooks are beautifully accessible.

There is no reason why a 15-year-old can not go through some.

When Rick in Rick and Morty says "school is not a place for smart people", he means that school is for sitting still and deliver on mediocre feats of thinking.

If you want to think the extraordinary, you have to read what extraordinary people have put out there.

The missing practical psychology

What if there is a way to use what the mind is good at, the way the mind palace works, and apply it to math, scientific concepts, writing, etc. etc.

Sometimes I came across a single sentence or such that elucidated a concept.

I will never forget:

First, you walk to the tree, then you can go up the tree.

This forever is my mnemonic of knowing that the first part of a 2D vector is the x coord or the horizontal axis.

What if there is an art and a technique to come up with these, and let children understand them at the right pace? I imagine some of those being larger stories, for instance with characters that symbolize concepts.

For instance, children remember Harry, Ron, Hermione, Dumbledore and Snape.

Why, then should it be hard to remember Nominative, Accusative, Genetive, Dative?

The answer is you don't use the brain of the child right, …yet.

There is a science and practice of practical psychology (Minsky 2007) missing.

What if 12th grade would take about 20 minutes if you just build up the right infrastructure of mnemonics, HaHa!

Minksy (Minsky 2007) randomly came up with an idea of an Imagine! book full of imagine exercises of gradually increasing difficulty. A similar idea to the mind palace, which works by imagination.

How to actually fix this?

… Biographical information on a sample of twenty men of genius suggests that the typical developmental pattern includes as important aspects: (1) a high degree of attention focused upon the child by parents and other adults, expressed in intensive educational measures and, usually, abundant love; (2) isolation from other children, especially outside the family; and (3) a rich efflorescence of fantasy as a reaction to the preceding conditions." … [If so, then] the mass education of our public school system is, in its way, a vast experiment on the effect of reducing all three factors to a minimum: accordingly, it should tend to suppress the occurrence of genius. —Harold McCurdy, 1960 10

The ultimate learning experience

In the The Diamond Age, we follow the path of a 4-year-old girl that gets to read The Primer, an advanced technological gadget and computer system in the form of a book. It first tells the child stories. Engaging and tailored to the psychology of the child. Then gradually teaches them science. It is also a companion, teaching about all things you might encounter in life.

The book is interactive. For instance, in later chapters, the user would program tutorial programs on it etc.

There is no reason this would be for children only. The gadget could figure out the perfect next thing for you to learn about.

We are almost close to being able to pull this off. Could be large language models with a big context about the learning state of the user. Plus some nice interactive, evolving computer environment.

Content

A Short History of Nearly Everything

Nice big history book with lots of history of science. Talks about the epic journey of how we understand what the universe is about.

And it has a children's version. But I don't know how good it is.

Unstoppable Us, Yuval Noah Harari

Astrophysics for Young People in a Hurry, Neil deGrasse Tyson

Outgrowing God, Richard Dawkins

This is for young people that realize religion does not make sense.

The Selfish Gene, Richard Dawkins

This book is so easy to read, you can read it early. For example at 12 - 14.

15+ and curious about how the brain works?

Start with How the Mind Works by Steven Pinker.

Follow the literary references trail to where you are interested.

  • Read Vehicles, experience what a great thinker can do to your mind. Building landscapes.
  • Other Minds: The Octopus, the Sea, and the Deep Origins of Consciousness, Peter Godfrey-Smith

    This is another very accessible book covering the history of thinking about the mind and thinking about how octopuses work.

  • The Man Who Mistook His Wife For A Hat: And Other Clinical Tales, Oliver Sacks

    To see what it means to observe people.

  • Neuroscience, Dale Purves

    Spend half a year with a textbook.

    Realize that textbooks are the best attempt of really smart people deep in the field to provide you with a journey into the field. All that is asked of you is to read and pay attention.

    Of course, it is very powerful to put each chapter into a region of your mind palace. Re-herse the day after. Then after 2 days, after 4 days, after a week, afterward keep the memory alive ad-lib.

  • The Society Of Mind, such a joyful ride into actually thinking about how the mind might work.

    Pure ideas, like philosophy and programming. And like good philosophy or programming, this builds layers of common sense ideas that are easy to follow.

Footnotes:

1

I was listening to a Minsky talk at TCNJ and Manfred Clynes was in the audience describing the same concept, for music performance:

https://youtu.be/gmeiJlbcVDo?t=3127

What he calls the feeling of it, the movement I call the mentations for performing a skill.

Emphasis on the fact that you need to unlearn and let go of mentations that are not useful or preventing a good performance.

Clynes and I agree, there is not much description and technique out there about such matters yet.

Surely, this is a concept that master jugglers, dart players and musicians all picked up at some point.

2

Thanks to Andrew Huberman.

3

In Surely You're Joking, Mr. Feynman! Feynman has a chapter on how he was using calculation tricks.

See Martin Gardner for inquiry on this trail.

5

The Logic of Scientific Discovery, Karl Popper (1959)

The Structure of Scientific Revolutions, Thomas Kuhn (1962)

I liked

Theory and Reality: An Introduction to the Philosophy of Science, Peter Godfrey-Smith (2003)

6

See memetics

7

Dawkins explains somewhere that he should have called it The Immortal Gene. He jokes that some critics are reading the book by title alone.

8

A Short History of Nearly Everything is an amazing ride through big history and the history of science and it has a kid's version.

9

See Alan Kay and Bret Victor to follow this trail.

And for an amazing rollercoaster of how computers were invented. How J.C.R. Licklider, Douglas Engelbart and others have inspired Kays's generation of computer hackers, see:

The Dream Machine: J.C.R. Licklider and the Revolution That Made Computing Personal.

10

Harold G. McCurdy, The Childhood Pattern of Genius. Horizon Magazine, May 1960, pp. 32-38

Date: 2023-04-30 Sun 12:26

About
Contact
]]>
https://faster-than-light-memes.xyz/dreaming-code.html dreaming-code 2022-10-20T23:59:59+00:00 dreaming-code

ftlm

dreaming-code

I produced source code in a dream once.

When I dream of coding it is usually sort of "disembodied" just concepts and problems + in the earlier part of the night.

What is the business of these early-night dreams?

Sleep mentations

NREM dreams are typically shorter, more fragmented, and more thought-like whereas REM dreams are longer, more emotional, and more bizarre

(Carr and Solomonova 2019).

These dreams from the early part of the night are more like thinking with some dream logic.

Here is an example from my dream diaries:

I have an internet connection in my brain and I need to connect to a database, then send some data to my feet. It is like thinking about the problem itself more, with some disembodied visuals of code. The coding itself is a little like being able to modify code blocks by raising an eyebrow or a finger. Every time I wake up I sort of want to "go back" to the problem, because I "know", I have almost solved it. Always so close.

Another quote from Carr and Solomonova:

Some use a more inclusive dreaming definition, such as ‘sleep mentation’, which is characterized by any cognitive activity, whereas the original concept of dreaming was more qualified as hallucinatory, predominantly visual, imagery (see also chapter 5). The questions used by an experimenter can alter a participant’s interpretation of dreaming. For example, the question, “what was going through your mind just before I called you”, will encourage more frequent dream reports than, “what were you dreaming about?”

I like the idea of calling these sleep mentation instead of dreams.

The night goes on - REM, NREM

Attributes such as length, bizarreness, and perceptual vividness increase for both NREM and REM sleep reports across the night

(Carr and Solomonova 2019).

Additionally, it is well known that in the later part of the night you have more REM sleep.

I was grouping dreams into 2 categories on a continuum:

  1. "Episodic" dreams, a reference to episodic memory. Featuring persons, places, situations with a story. In many cases featuring a main character. Later in the night.
  2. "Non-Episodic" dreams: Usually no characters, no real story. More like thinking about a problem. Or tool/toy/concept usage in the abstract somehow. As if the brain parts for the tool usage are online without any of the storytelling, and little of the "world integrating" parts. More abstract, fewer visuals and perceptions (low "vividness"). Also, extremely hard to remember any content. Also, it is very hard (impossible?) to become lucid during one of those. Earlier in the night.

Source code in a vivid dream

It did happen to me recently halfway through the night. A dream purely about coding but more on the side of what I would call episodic. This was a complete first time. Usually, code dreams where these ephemeral problem-solve dreams.

I was dreaming about my emacs config.

I recall a visual of colored source code (+ content!). There was also a bit of a first-person main character, thinking along the lines of "I want to make this part smoother…". Here it is:

;; This code came to me in a dream almost verbatim:
(add-hook 'kill-emacs-hook #'save-some-buffers)

I was able to type in this code the next morning, haha!

Date: 2022-10-20 Thu 19:18

About
Contact
]]>
https://faster-than-light-memes.xyz/scratching-in-space.html scratching-in-space 2022-10-04T23:59:59+00:00 scratching-in-space

ftlm

scratching-in-space

Emacs scratch buffers have place oriented design.

A simple alternative: make files.

Musings about persistent scratch technology.

Introduction

If you ever typed something in a buffer called *scratch* you will inevitably have found yourself in this situation:

  1. Just typed some awesome code.
  2. Kill scratch buffer accidentally or unthinkingly.
  3. That awesome text is gone forever… and it hurts.

I did try persistent-scratch, in its simplest form, it persists your scratch buffer across sessions. You still end up having one place for your "current" scratch. It just did not click with me.

The whole idea of a scratch buffer might be obsolete (Xah Lee 2008).

What I want:

  1. Convenient way of writing some code interactively.
  2. Persist it.

scratching in space

Our disk space is vast, and emacs is great at creating files.

We can be like Sherlock Holmes and never throw our notes away.

Horde those scratches. Put them in git. Now you can grep through them, see what you were scratching years in the past.

I have a dir called ~/scratches with all my scratches. This is a bit similar to denote, which I use for note-taking.

here is my current hack for this:

(defvar mememacs/scratch-dir (expand-file-name "~/scratch"))
(defun mememacs/latest-scratch (suffix)
  (unless (file-exists-p mememacs/scratch-dir)
    (make-directory mememacs/scratch-dir))
  (when-let
      ((f
        (car
         (cl-remove-if-not
          (lambda (it)
            (and (string-suffix-p suffix it)
                 (not (string-match-p "#" it))))
          (process-lines
           "ls"
           "-A"
           "-t"
           mememacs/scratch-dir)))))
    (expand-file-name f mememacs/scratch-dir)))

(defun mememacs/new-scratch-name (suffix)
  (unless (file-exists-p
           mememacs/scratch-dir)
    (make-directory
     mememacs/scratch-dir))
  (expand-file-name
   (format "%s.%s" (make-temp-name "scratch-") suffix)
   mememacs/scratch-dir))

(defun mm/scratch
    (&optional create-new suffix)
  "Visit the latest scratch file with `suffix` (a file extension).
With prefix arg make a new file."
  (interactive
   (list current-prefix-arg
         (completing-read "scratch filetype: " '("cljs" "clj"))))
  (let* ((latest (mememacs/latest-scratch suffix))
         (buff
          (find-file-noselect
           (if (or create-new (not latest))
               (mememacs/new-scratch-name suffix)
             latest))))
    (pop-to-buffer-same-window buff)
    (when (eq major-mode 'emacs-lisp-mode)
      (elisp-enable-lexical-binding))
    buff))

(defun mm/scratch-el (&optional arg)
  (interactive "P")
  (mm/scratch arg "el"))
keybinds:
leader bs #'mm/scratch-el
leader bS #'mm/scratch

With a nice keybind (leader b s) I go to my current scratch file - the latest modified file in my scratch dir. With prefix-arg, it makes a new file. A second bind will ask me to make a clj or cljs file.

clojure scratch repl?

Whatever. I just do this:

echo '{}' > ~/scratch/bb.edn

Now I can start a cider repl with bb in my scratch dir. If you want to be asked for bb or jvm:

echo '{}' > ~/scratch/deps.edn

Also nbb: A nice way to scratch some cljs + javascript + node: It currently requires some workaround that you can find here.

Date: 2022-10-04 Tue 16:04

About
Contact
]]>
https://faster-than-light-memes.xyz/jacking-nbb.html jacking-nbb 2022-10-14T23:59:59+00:00 jacking-nbb

ftlm

jacking-nbb

A cider jack in command for nbb.

Introduction

Nbb is a beatiful parasite. A node script that is an interpreter for Clojurescript. You get the upsides of Node.js + it is Clojure.

Want to try out some npm packages? Sure, just make a package.json, works instant, is part of the design principles of nbb.

You get Clojures immutable data structures, polymorphism constructs, a repl, etc.

On the tooling side, you might be surprised how far nbb gets with very little.

Scratching (in space) is very usefull and nbb is a natural fit for a quick cljs repl.

Update 2:

You can jack in Nbb nowadays with cider-jack-in-cljs then select nbb.

Alternatively, if you have cider d292d8d7eea5d3a12c138687133761a7256b1705

We can define jack in commands like so:

(defun cider-jack-in-nbb-2 ()
  "Start a Cider nREPL server with the `nbb nrepl-server` command."
  (interactive)
  (cider-jack-in '(:jack-in-cmd "nbb nrepl-server")))

You can also set a project jack-in-cmd in .dir-locals by setting cider-jack-in-cmd locally.

((nil
  (cider-jack-in-cmd . "nbb nrepl-server")))

This is especially useful, if you have an nbb project. You can now call cider-jack-in-clj without the need to select anything further anymore.

Note: Commands and elisp below are workarounds we do not need anymore because Cider supports Nbb much better since recently!

Update:

This is no longer needed with cider 1.6. There is a dedicated nbb cider build tool now. I still also think my proposal here would be useful.

;; the equivalent of the proposed change
(advice-add
 'cider--update-jack-in-cmd
 :before-until
 (defun cider-dont-update-jack-in-cmd-when-given (params)
   (when (plist-get params :jack-in-cmd) params)))

;; now a nbb jack in command becomes:
(cider-jack-in '(:jack-in-cmd "nbb nrepl-server"))

Jack-in command

cider repl workaround

We currently need this workaround for sci-based cljs repls for cider:

(cider-register-cljs-repl-type 'nbb-or-scittle-or-joyride "(+ 1 2 3)")

(defun mm/cider-connected-hook ()
  (when (eq 'nbb-or-scittle-or-joyride cider-cljs-repl-type)
    (setq-local cider-show-error-buffer nil)
    (cider-set-repl-type 'cljs)))

(add-hook 'cider-connected-hook #'mm/cider-connected-hook)

Note: You do not need this workaround in recent versions of cider anymore.

the command

Unfortunately, cider does not have the concept of a nbb repl currently. I think cider-jack-in-resolve-command and similar functions could be thrown out and replaced with data.

So I went 1 level deeper to bypass ciders auto-detection of project type (+ jack in cmd):

(defun mm/cider-jack-in-nbb ()
  "Start a nbb nrepl process and connect."
  (interactive)
  (let* ((cider-allow-jack-in-without-project t)
         (orig-buffer (current-buffer))
         (params '(:jack-in-cmd "nbb nrepl-server :port 0"
                   :cljs-repl-type nbb-or-scittle-or-joyride))
         (params (cider--update-project-dir
                  params)))
    (nrepl-start-server-process
     (plist-get params :project-dir)
     (plist-get params :jack-in-cmd)
     (lambda (server-buffer)
       (with-current-buffer
           orig-buffer
         (cider-connect-sibling-cljs
          params
          server-buffer))))))

This is what I wanted to say:

(defun mm/cider-jack-in-nbb ()
  "Start an nbb nrepl process and connect."
  (interactive)
  (cider-jack-in-cljs
   '(:jack-in-cmd "nbb nrepl-server :port 0"
     :cljs-repl-type nbb-or-scittle-or-joyride)))

hack for the remaining issue

With this, you should get an error "ClojureScript is not available…". Until there is a fix in cider, you can hack it by redefining cider-verify-clojurescript-is-present:

;;; FIXME: https://github.com/clojure-emacs/cider/issues/3255
(defun cider-verify-clojurescript-is-present ()
  "Check whether ClojureScript is present."
  (unless (nrepl-dict-get (cider-sync-tooling-eval "cljs.core/inc") "value")
    (user-error "ClojureScript is not available.  See https://docs.cider.mx/cider/basics/clojurescript for details")))

Results

Hehe, insta nbb repl. Works good.

Date: 2022-10-14 Fri 10:22

About
Contact
]]>
https://faster-than-light-memes.xyz/clojure-function-psychology-quiz.html Which Clojure Core Function are You? 2023-02-18T23:59:59+00:00 Which Clojure Core Function are You?

ftlm

Which Clojure Core Function are You?

Which Clojure Core Function are You?

Introduction

Since Chat-Gtp generating a certain kind of text is starting to be a solved problem.

I sort of liked what it had to say about what it means to be a fire bender in Avatar.

For some reason, I decided to make Clojure core function psychology puzzle, along the lines of What Clojure Function Are You? but also combine it with Avatar elements.

Avatar is cool

Is it just me or is there some Avatar The Last Airbender affinity in the Clojure ecosystem?

There is a database called Asami and Stuart Halloway is cosplaying as Aang somewhere.

Anyway, I dig Avatar myself, the whole world and the bending fit together very organically. Plus it sort of comes with thoughtfulness. And the bending, the choreography and the philosophy of it. Fire is anger but also life, it is about control. And with the highest control and focus you can lightning bend.

The bending choreography is amazing. Yes, I mean the choreography of the animated characters. It is inspired by Thai-Chi and other disciplines. Every element (fire, water, earth, air) has its style. It is one of the best magic systems I have encountered. The animations + sounds have a physical oomph. I almost feel like I know how it would be to bend. Water is fluent and dynamic, earth is solid and unmoving, fire is pure power, air is flying around and seeing the big picture.

Prompt engineering, Chat-Gpt makes a quiz

prompt 1

Help me make a quiz in the style of "Find out your harry potter house by answering those 6 psychological questions".

The quiz asks psychological questions that establish some personality traits of the user.

But we tell the user in the end which clojure.core function fits their personality.

Say one of those:

  • conj
  • reduce
  • juxt
  • swap!
  • into

We also map those with elements and bender power to Avatar the last airbender. For the bender psychological traits there are the elements and then there is another one for characters like Asami, who uses technology instead of bending.

Map the clojure core functions to avatar elements with a short description why.

prompt 1 end

I then kept asking a little, to get hiccup formatted data etc.

Result

I went and made a scittle re-frame app.

Code and link to the quiz!.

Date: 2023-02-18 Sat 16:55

About
Contact
]]>