Recent submissions

Comment · 2 months ago
It really depends on what your character is. I like to start from the basics and build up.

I would start from a completely vanilla emacs (on package emacs-pgtk--that is the graphical version), then enable Options > Cut/Paste with C-x/C-c/C-v CUA mode, then Options > Save Options.

I like and use Emacs, but it is showing its age. The defaults are all bad--but the possible end result you CAN configure is pretty modern [1]. I use emacs for programming (Rust including IDE, intellisense, go to definition, debugging, the works), git (magit), for email (mu4e), and for scientific writing (xenops, latex including preview), pdf notetaker (org-noter), looking at installed system "info" documentation (info), tramp (transparently open files from other computers in your emacs), org mode (note taking, Zettelkasten including search).

org mode is awesome. It's the obvious end result of what happens when you use emacs for everything: you can have org documents contain emacs lisp snippets (or shell scripts) that you then can point at and execute--or not. The resulting output of those commands can go into the same org document there--or not. It's like Jupyter Notebook in that way.

Personally, I got into emacs because I wanted to do more Lisp. You will (automatically) learn a little Lisp to be able to use emacs properly.

I think the best way to understand Emacs is it's a Lisp VM with an editor attached. The editor is almost all malleable at runtime--it's clearly made for programmers. I almost never restart emacs, I just mutate it on the go. It has a debugger and profiler in the Lisp VM, accessible right in the emacs Options menu, in case your weird mutations act up (they will). The feel is like the old home computer basic interpreters, just better. Including getting weird emacs Lisp snippets from magazines (errr... websites) and typing them in, typos and all.

I would start reading at https://ftp.gnu.org/old-gnu/Manuals/emacs-21.2/html_chapter/... (yes, that specific page).

The emacs GUI renderer is surprisingly capable, it can do syntax highlighting (font "locking", fontifying), pictures, hover, variable width fonts (including variable-width tables--vtable) and stuff like that (i.e. your buffer can contain those or you can synthesize those on the fly).

When in emacs, you can press Alt-x (M- means Alt- , so docs say "M-x" [2]) and have a LOT of existing commands at your fingertips. I recommend M-x magit to get a taste of what is possible for anyone to write in emacs gui.

Everything there is in emacs can be looked at via reflection. Try M-x describe-mode, or M-x describe-face, or M-x describe-key (to answer wtf does the key combo "x" do), M-x info, M-x woman, M-x help. Emacs has hyperlinks and pretty good mouse support.

Start customizing Emacs settings using M-x customize-variable (that's Options > Customize Emacs), only later by editing init.el manually.

Remember C-g (ctrl-g), which stops the Lisp interpreter's evaluation of whatever it is doing (like Ctrl-c would be in the terminal, but ctrl-c is Copy to Clipboard, or something else--never is Ctrl-c "cancel" in emacs).

[1] I have a 5000 line emacs config directory that grew over the years. This is not a boast. I hate that it's not the default. See https://github.com/daym/emacs-config -- please don't try using the entire thing. Cobble together your config using copy&paste like I did (start at init.el) :) Don't restart emacs, use the "scratch" buffer and evaluate snippets there.

[2] It's not because they are contrarian, it's because the original emacs keyboard had a Meta key. emacs is OLD.

Comment · 4 months ago
waypipe works very fine.

    waypipe ssh XXX
Comment · 8 months ago
I'm only using NanoClaw, but I like that I could (and did) just review the code it has, and that it uses containers for each agent (so I can have different WhatsApp groups working on different things and they can't interfere with each other), and that I could (and did) just swap those containers out easily for guix shell containers.

I am pretty confident that I know how the agent containerization works. In general there's really not a lot of complexity there at all.

If one wants, one can just (ask Claude to) add whatever functionality, or (and that's what I did) just use Claude skills (without adapting NanoClaw any further) and be done with.

What is annoying is that their policy is instead of integrating extra functionality upstream, they prefer you to keep it for yourself. That means I have to either not update from upstream or I am the king of the (useless so far--just rearranging the deck chairs) merge conflicts every single time. So one of the main reasons for contributing to upstream is gone and you keep having to re-integrate stuff into your fork.

Comment · 9 months ago
For what it's worth, there is this vscode extension https://github.com/realDestroyer/org-vscode/ which is pretty neat and can do org-mode task tracking, calendar and agenda view--and HTML preview.
Comment · 1 year ago
Just as you can select whatever railroad gauge as a country (if you also build compatible trains, obviously) and have it work just fine no matter what you select--until you try to connect it to another country and then you need to have converters--, some physical theories have gauges like this that you can choose however you want and it will work fine (and be equivalent to a theory in any other gauge)--but if you want the theory to work with the next guy's theory you have to have converters.
Comment · 1 year ago
>Is this level of fear typical or reasonable?

Of course. Also with regular customer projects. Even without AI--but of course having an idiot be able to execute commands on your PC makes the risk higher.

> If so, why doesn’t Anthropic / AI code gen providers offer this type of service?

Why? Separate the concerns. Isolation is a concern depending on my own risk appetite. I do not want stuff to decide on my behalf what's inside the container and what's outside. That said, they do have devcontainer support (like the article says).

>Hard to believe Anthropic is not secure in some sense — like what if Claude Code is already inside some container-like thing?

It's a node program. It does ask you about every command it's gonna execute before it does it, though.

>Is it actually true that Claude cannot bust out of the container?

There are (sporadic) container escape exploits--but it's much harder than not having a container.

You can also use a qemu vm. Good luck escaping that.

Or an extra user account--I'm thinking of doing that next.

Comment · 1 year ago
It stops at GNU Mes and hex0.

Bootstrapping everything is exactly how it's done correctly--and how it's actually done in practice in Guix.

I mean sure if you have a business to run you outsource this part to someone else--but you seem to think it's not done at all.

Supply chain attacks have been happening pretty much non-stop the past years. Think it's a good idea to use binary artifacts you don't know how they were made (and thus what's in them)? Especially for build tools, compilers and interpreters.

>And why is that location more valid of a decision than the one that doesn't require building the build system from source?

Because you only have to review a 250 Byte binary (implementing an assembler) manually. Everything else is indeed built from source, including make, all the way up to Pypy, Go, Java and .NET (and indeed Chromium).

Comment · 1 year ago
>It has a lambda there. In many programming languages, and the way human beings read this, say that "when there is a lambda, whatever is inside is evaluated only when you call it".

What is inside the lambda is to the right of the ":". That is indeed evaluated only when you call it.

>But it is good that people are aware that it is an error in design, so new programming languages don't fall into the same error.

Python didn't "fall" into that "error". That was a deliberate design decision and in my opinion it is correct. Scheme is the same way, too.

Note that you only have a "problem" if you mutate the list (instead of functional programming) which would be weird to do in 2025.

>For an equivalent error that did get fixed, many Lisps used to have dynamic scoping for variables instead of lexical scoping. It was people critizing that decision that lead to pretty much all modern programming languages to use lexical scoping, including python.

Both are pretty useful (and both are still there, especially in Python and Lisp!). I see what you mean, though: lexical scoping is a better default for local variables.

But having weird lazy-sometimes evaluation would NOT be a better default.

If you had it, when exactly would it force the lazy evaluation?

    def g():
        print('HA')
        return 7

    def f(x=lazy: [g()]):
        pass
^ Does that call g?

    def f(x=lazy: [g()]):
        print(x)
^ How about now?

    def f(x=lazy: [g()]):
        if False:
            print(x)
^ How about now?

    def f(x=lazy: [g()]):
        if random() > 42: # If random() returns a value from 0 to 1
            print(x)
^ How about now?

    def f(x=lazy: [g()]):
        if random() > 42:
            print(x)
        else:
            print(x)
            print(x)
^ How about now? And how often?

    def f(x=lazy: [g()]):
        x = 3
        if random() > 42:
            print(x)
^ How about now?

Think about the implications of what you are suggesting.

Thankfully, we do have "lazy" and it's called "lambda" and it does what you would expect:

If you absolutely need it (you don't :P) you can do it explicitly:

    def f(x=None, x_defaulter=lambda: []):
        x = x if x is not None else x_defaulter()
Or do it like a normal person:

    def f(x=None):
        x = x if x is not None else []
Explicit is better than implicit.

Guido van Rossum would (correctly) veto anything that hid control flow from the user like having a function call sometimes evaluate the defaulter and sometimes not.

Comment · 1 year ago
There's always tension between language simplicity (and thus cognitive load of the programmers) and features. Compare Scheme with Common Lisp.

The idea in Python is:

1. Statements are executed line by line in order (statement by statement).

2. One of the statements is "def", which executes a definition.

3. Whatever arguments you have are strictly evaluated. For example f(g(h([]))), it evaluates [] (yielding a new empty list), then evaluates h([]) (always, no matter whether g uses it), then evaluates g(...), then evaluates f(...).

So if you have

def foo(x = []): ...

that immediately defines

foo = (lambda x = []: ...)

For that, it has to immediately evaluate [] (like it always does anywhere!). So how is this not exactly what it should do?

Some people complain about the following:

    class A:
        x = 3
        y = x + 2
That now, x is a class variable (NOT an instance variable). And so is y. And the latter's value is 5. It doesn't try to second-guess whether you maybe mean any later value of x. No. The value of y is 5.

For example:

    a = A()
    assert a.__class__.x == 3
    assert a.x == 3
    a.__class__.x = 10
    b = A()
    assert b.x == 10
succeeds.

But it just evaluates each line in the class definition statement by statement when defining the class. Simple!

Complicating the Python evaluation model (that's in effect what you are implying) is not worth doing. And in any case, changing the evaluation model of the world's most used programming language (and in production in all countries of the world) in 2025 or any later date is a no go right there.

If you want a complicated (more featureful) evaluation model, just use C++ or Ruby. Sometimes they are the right choice.

Comment · 1 year ago
There's also https://github.com/dspinellis/git-issue which has much fewer dependencies.
Comment · 1 year ago

    guix build --with-configure-flag="jq=CFLAGS=-O3" jq
If you want it to be permanent, then you can use a guix home profile (that's a declarative configuration of your home directory) with a patch function in the package list there:

    (define llama-tune
      (options->transformation `((tune . "znver3")))) ; Zen 3

    (home-environment
     (packages (list (llama-tune (specification->package "llama")))))
or:

    (define jq-patch
      (options->transformation `((with-configure-flag . "jq=CFLAGS=-O3"))))
[...]

    (jq-patch (specification->package "jq"))
[...]

You can also write a 10 line guile script to automatically do it for all dependencies (I sometimes do--for example for emacs). That would cause a massive rebuild, though.

>The most pain-free option I can think of is the --tune flag (which is similar to applying -march=native), but

> packages have to be defined as tunable for it to work (and not many are).

We did it that way on purpose--from prior experience, otherwise, you would get a combinatorial explosion of different package combinations.

If it does help for some package X, please email us a 2 line patch adding (tunable? . #t) to that one package.

If you do use --tune, it will tune everything that is tuneable in the dependency graph. But at least all dependents (not dependencies) will be just grafted--not be rebuilt.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton