Corbin

joined 2 years ago
[–] Corbin@programming.dev 2 points 21 hours ago (1 children)

My $HOME is recreated on boot and lives in RAM. I don't care what gets written there; if I didn't know about it and intend to save it to disk, then it won't be saved. It would be nice if tools were not offenders here, but that doesn't mean that we can't defend ourselves somewhat.

[–] Corbin@programming.dev 2 points 4 days ago

This is a common misconception! It is true that, of the Smalltalk descendants, Python was not designed for speed like Self or Java; but it was not designed to be slow or difficult to compile. The main technique required to implement a Python JIT is virtualizable objects, which allows the JIT to temporarily desynchronize the contents of registers from the contents of the heap; it's not obvious and wasn't in the first few iterations of PyPy. Additionally, it turns out that tracing the meta-level (see docs or the paper) is a key trick: instead of JIT'ing the Python program, the JIT operates on the interpreter, on the Python VM itself!

[–] Corbin@programming.dev 3 points 5 days ago

I gather that you don't actually use PyPy much. On average, I expect PyPy to deliver over a 3x speedup. The main issue is that people have built upon slow libraries like Numpy that only seem fast because CPython is even slower.

The reason that CPython cannot have a JIT added on is architectural and political. The CPython core team refuses to learn lessons from PyPy.

[–] Corbin@programming.dev 2 points 6 days ago

I've used this driver to stream a write to a disc. It's unfortunate that we can't have this technology, but it's always been janky, and these days it costs less than $1 of RAM to buffer a CD or $5 to buffer a DVD before writing.

[–] Corbin@programming.dev 1 points 1 week ago

Some of those details are portable, particularly the behavior of code objects. Function declarations (def statements) bind code objects to names within a namespace; binding within a class namespace will create methods by calling the declared metaclass, which defaults to the type() builtin type object.

Some other details are not portable. CPython stores code objects on the C heap and allocates generic closures; it supports either a dict from strings to locals, or user-declared slots naming a tuple of locals. PyPy automatically computes slots in all cases and supports the dict as a special case. Threads generally share a single heap per interpreter, so the creation of threads doesn't matter for declaring or instantiating objects; note that the community makes this work by pushing the convention that .__init__() methods should not do computation and instead should merely initialize the locals, akin to similar conventions in C++. That said, Jython threads are Java threads, not OS threads like in CPython or PyPy, so normal assumptions about threading may not hold.

You will have to let go of some of your practices around memory management. Python is memory-safe and garbage-collected by default; while sometimes you'll want to remove names or map keys with del, it usually isn't necessary. Similarly, while there are maybe a half-dozen ways to customize class creation and memory layout, it's almost never actually necessary to use more than one of them at a time. Instead, stick to writing Pythonic code, and let runtimes like PyPy worry about performance. PyPy goes fast by simplifying what happens under the hood; if it exposed guaranteed internal structure then it would be slower.

[–] Corbin@programming.dev 2 points 1 week ago

In terms of the standard principal programming paradigms, Python is on the right-hand side in the "Shared state" column. Note two interesting things: first, Python's box is represented by Java and OCaml; second, the box has two labels, "Sequential object-oriented programming" and "Stateful functional programming". Python is technically a prototype-based language like ECMAScript, but it can be seen as either object-oriented or functional depending on whether we think of prototypes as classes or closures respectively.

Note that unlike "Imperative programming", represented by Pascal and C, Python has closures. It does have closure quirk, also called lambda quirk, which ruins an otherwise-lexically-scoped language, but folks with lots of Python experience are used to working around closure quirk. Python functions are not procedures; they are sugar for objects with a .__call__() method.

If this is your first time with the principal paradigms, please keep in mind the following quotes. First, from the associated book:

More is not better or worse than less, just different.

That is, Turing-completeness doesn't have a canonical set of computational features. Second, from the chart PDF:

Two languages that implement the same paradigm can nevertheless have very different "flavors" for the programmer, because they make different choices on what programming techniques and styles to facilitate.

[–] Corbin@programming.dev 4 points 1 week ago

This is for short-lived cloud-allocated (virtual) machines which have an IPv4 address but not necessarily a DNS presence. When there are more than a handful of machines, name management becomes its own unique pain; often, the domain names of such a machine are an opaque string of numbers under some subdomain, and managing the name is not different from managing the raw IP address instead. Similarly, for the case of many machines all serving a wildcard (e.g. a parking page) allocating a single IP-address certificate might be preferable to copying the wildcard certificate to each machine.

As you point out, though, SSH exists and has accumulated several decades of key-management theory. Using HTTPS instead of SSH for two machines with one owner is definitely not what I would do. I've worked at all scales from homelabs to Google and I can't imagine using IP-address certificates for any of it.

Now, with all of that said, if Let's Encrypt were available over e.g. Yggdrasil then there would be a use-case for giving certificates directly to IPv6 addresses and extending PKI to the entire Yggdrasil VPN. That seems like a stretch though.

[–] Corbin@programming.dev 4 points 2 weeks ago

Nix comes closest. The biggest issue with Nix is that it does not admit a clean simple LL/LR grammar, but I think it admits a PEG, which is fine for practical work. The ecosystem could use more independent implementations and tooling, but I haven't found any deficiencies with the language that would make me prefer e.g. Guile Scheme's larger standard library and richer types.

HCL is another option. It's not awful, but it's verbose when trying to do anything higher-order, and it wasn't intended to directly represent lambda-style subroutines. Guile Scheme, as used in Guix, is clearly capable, but requires embedding a fairly large standard library or having to NIH common routines; similar problems plague Lua or Python.

I think that your question has an interesting framing. My first answer was to mention jq and the relational pipes toolkit, but those are still run from a top-level shell. For example, I suppose that there's two things that you can do with JSON: you can manipulate it and I would use jq for that, or you can load it as a datastructure into a (build) action and I would use Nix for that. jq is close to ideal for its particular formalization, but relational pipes are still evolving and I think that there are further simplifications that could be made.

[–] Corbin@programming.dev 2 points 1 month ago

I mirror some specific repositories of mine to GH specifically so that they will be included in Copilot's training data. It amuses me when chatbots think that they know Lojban or Metamath, can't distinguish RPython from Python 2.7, or think that Monte is Mathematica. Some languages, particularly Zaddy, are likely so confusing and have such small corpora that chatbots will never be able to generate them; their inclusion in training data is possibly unhelpful.

No, I don't keep everything there. In particular Cammy is only publically available via the notoriously unreliable OSDN mirror because I don't trust folks to understand purity, functions, and category theory.

[–] Corbin@programming.dev 1 points 1 month ago

It's a multi-decade tradition that goes back to Project Athena, a collaboration between MIT, DEC, and IBM. X11's reference implementation has been the main flag-bearer of the license, propagating it forward to many freedesktop.org projects.

[–] Corbin@programming.dev 2 points 1 month ago (1 children)

Also, the author has a standalone blog post on the topic from 2011, Expression Parsing Made Easy.

[–] Corbin@programming.dev 2 points 1 month ago

Put a rescue distro on a USB stick. When you first boot the laptop, use the rescue distro. Write down the USB IDs (lsusb) and PCI IDs (lspci). Read through the kernel boot log (sudo dmesg | less) and write down the names of any kernel drivers that might matter; WiFi, GPUs, USB bridges, and keyboard layouts are important in particular. For laptops, look up manufacturer-specific drivers for keyboards, fans, and power management.

Linux requires about 8MiB of RAM to boot. The entire netbook movement relied on machines with 2GiB or less; I remember putting Linux onto a 2GiB Sony VAIO that had struggled to boot Windows. Your laptops aren't too small, but you may be choosing distros with poor hardware support or large monolithic packages. I bet that one of Debian, Gentoo, or NixOS would boot on those machines that still work; of those, Debian is probably easiest.

Old laptops sucks. Windows use to be very efficient. XP and 7 has held up very well after all these years. And most importantly Linux isn’t a one size fits all solution.

Nah, Windows sucked back then too. If a machine boots Windows XP or Windows 7, then it can easily be made to boot an out-of-the-box Linux distro. The Asus machine you listed might have some boot issues, but the Acer and Dell do not appear different from any of the Acers or Dells that I've put Linux on in the past decade. My daily driver is a $150 refurbished Dell Latitude 5390 running NixOS.

 

Bret Victor wants to sell Dynamicland to cities.

I'm submitting this for public comment because Victor is a coward who cannot take peer review in public. Ironically, this is part of the problem with his recent push to adapt Dynamicland for public spaces; Victor's projects have spent years insisting that physical access control is equivalent to proper capability safety, and now he is left with only nebulous promises of protecting the public from surveillance while rolling out a public surveillance system -- sorry, a "computational public space."

 

I'm happy to finally release this flake; it's been on my plate for months but bigger things kept getting in the way.

Let me know here or @corbin@defcon.social if you successfully run any interpreter on any system besides amd64 Linux.

 

The abstract:

This paper presents μKanren, a minimalist language in the miniKanren family of relational (logic) programming languages. Its implementation comprises fewer than 40 lines of Scheme. We motivate the need for a minimalist miniKanren language, and iteratively develop a complete search strategy. Finally, we demonstrate that through sufcient user-level features one regains much of the expressiveness of other miniKanren languages. In our opinion its brevity and simple semantics make μKanren uniquely elegant.

 

Everybody's talking about colored and effectful functions again, so I'm resharing this short note about a category-theoretic approach to colored functions.

view more: next ›