<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>zenmaya&apos;s corner</title><description/><link>https://zenmaya.xyz</link><item><title>Carving out your own Internet</title><link>https://zenmaya.xyz/blog/carving-out-your-own-internet</link><guid isPermaLink="true">https://zenmaya.xyz/blog/carving-out-your-own-internet</guid><description>Not unlike others I have been disappointed how the Internet is in this day and age. From endless algorithms, to slop websites and corporate mazes, the internet is not what it used to be. I do not want to seem like an old enby yelling at a cloud. I am a young enby yelling at the Cloud, and I wanted to share how I managed to get closer to an internet I wanted.
</description><pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;
&lt;h1&gt;The Search&lt;/h1&gt;
&lt;p&gt;The long-standing issue with searching has been always the endless
advertisments, websites that regurgitate what others have written and
this problem has only been exacerbated by the introduction of the LLM
Slop generators.&lt;/p&gt;
&lt;p&gt;There are a few paths that can help you with your search duties. I
personally opted into the paid solution of &lt;a href=&quot;https://kagi.com&quot;&gt;kagi&lt;/a&gt;,
but I understand if it is not affordable for some&lt;a href=&quot;#fn1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, and I will provide
the solution that is completely free and has at least some of the
advantages.&lt;/p&gt;
&lt;section&gt;
&lt;h2&gt;kagi&lt;/h2&gt;
&lt;p&gt;kagi is a paid search engine. As you may say, why would I pay for a
search engine? The thing is, operating a search engine costs
money. And it is a never-ending job, you can’t just index all the
sites once. The content changes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kagi also offers LLM tools which I don’t particularly enjoy, but you
are very much free not to use them as I don’t.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What differentiates kagi is their customizability. It offers a way to
disable slop websites right from it’s interface. There is a free
solution as I will mention later, but there are other advantages.&lt;/p&gt;
&lt;p&gt;kagi has different modes for indexing, one of the built-in ones is
“Academic” which restricts results only to academic publications! No
more google scholar, you can search relevant results right from your
search engine, finally. As a person who does occasionally some
research this is greatly appreciated.&lt;/p&gt;
&lt;p&gt;Other big advantage is kagi’s ability to rank or derank websites. Do
you want to push wikipedia higher? Yes you can. Just click the shield
icon. This feature is especially useful when there are two websites
offering almost the same content (looking at you, &lt;a&gt;nixos.wiki&lt;/a&gt; and
&lt;a&gt;wiki.nixos.org&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;One use of LLMs that is greatly appreciated is the context aware
translation. kagi has gone one step further and the translate feature
can also give you grammar, declinations and other explanations of the
feature which aids greatly with language learning.&lt;/p&gt;
&lt;p&gt;Not to be on a high note too long, kagi has some not-so-great things
about it. Firstly, it’s very “AI” enabled by default. You can disable
it, but it definitely supports “AI” as something that should exist in
the future. Secondly, it is a VC funded Sillicon Valley company, which
makes me fear for it’s future. For me the negatives do not outweigh
the benefits, but I will let you be your own judge.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;searx, searxng, searxngreloaded, searxnewgame+ and others&lt;/h2&gt;
&lt;p&gt;I will briefly provide a list of other search engines and what was my
experience with them. Most of them are serviceable, but I had issues
with all of them, in one way or the other.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
searx – unmaintained, you should prefer searxng
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://github.com/searxng/searxng&quot;&gt;searxng&lt;/a&gt; – it’s a “meta”-search
engine, which means that it only aggregates anonymized results from
other search engines. There is no central service and you need to
either pick an instance, or host it yourself.
It can be very hit or miss. Sometimes the server can be temporarily
banned and you need to use a different provider. If you pick a good
instance it can be definitely usable.
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://duckduckgo.com&quot;&gt;duckduckgo&lt;/a&gt; – a us based search engine
based on bing. definitely usable, but I had my fair share of it
missing results. Also I’m not so sure on how much data they actually
collect.
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://startpage.com&quot;&gt;startpage&lt;/a&gt; – europe based search engine,
based on anonymized google results with supposedly “anonimized”
ads. I have had some issues using it from public wifis, as the
service banned the IP for abuse.
&lt;/li&gt;
&lt;li&gt;
google – hell no.
&lt;/li&gt;
&lt;li&gt;
bing – why.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Deslopify your results&lt;/h2&gt;
&lt;p&gt;You know the feeling, you search for your very specific query just to
click on a website that is somehow not saying anything useful, and
after a little bit of reading you realize you have been reading thrice
sloppified junk from the official docs. Say no more. With
&lt;a href=&quot;https://ublacklist.github.io&quot;&gt;uBlacklist&lt;/a&gt; and &lt;a href=&quot;https://github.com/laylavish/uBlockOrigin-HUGE-AI-Blocklist&quot;&gt;Huge AI
Blocklist&lt;/a&gt;
you can finally rest easy knowing that your results are thrice
sloppified junk that was made by humans.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Browsers&lt;/h1&gt;
&lt;p&gt;There are many different browsers available for some platforms, but I
have not tested them. If browser here exists on your platform,
probably it’s a good choice (if it’s not Firefox on iOS). I would stay
clear from any Chromium based browser, due to firstly due to Google,
it’s monopoly over browsers and their spyware, secondly, because
&lt;a href=&quot;https://ublockorigin.com/#manifest-v3-section&quot;&gt;Manifest V3, that prevents adblockers from blocking ads&lt;/a&gt;.&lt;/p&gt;
&lt;section&gt;
&lt;h2&gt;Linux&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
Firefox – I hope I don’t need to convince you why using anything 
made by google is bad. Firefox has made some questionable choices, 
but it still remains as the most competetive alternative to Blink 
(chromium renderer) based browsers.
&lt;/li&gt;
&lt;li&gt;
Icefox – a libre firefox soft-fork. For some reason Icefox is dead 
set on setting libreJS as the default, making most of the web unusable.
Otherwise I welcome the choice of a fully libre browser.
&lt;/li&gt;
&lt;li&gt;
LibreWolf – a fork of firefox with private defaults, if you don’t
need Firefox Sync it’s a perfectly good alternative to Firefox.
&lt;/li&gt;
&lt;li&gt;
Zen – a reimagined browser, the UI is really pretty. My only issue
is that it is much more memory hungry than Firefox, and since I’m
employed as a web developer, I struggle with 32GB of RAM
constantly. I had to switch back to plain Firefox.
&lt;/li&gt;
&lt;li&gt;
Gnome Web – Webkit-based browser, can definitely work for some
people, the UI is well integrated into Gnome and I find it very 
nice, however it struggles with a lot of website (due to the nature
of Webkit) and is noticeably slower than Firefox.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;iOS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
Firefox Focus – if you are a chronic tab hoarder, a browser with
just one window is the thing you will love. A search and forget
browser I use for quickly lookup stuff.
&lt;/li&gt;
&lt;li&gt;
Orion – built on Safari, from people behind kagi, but one of the
few browsers that has extension support, so you can install uBlock
Origin and others
&lt;/li&gt;
&lt;li&gt;
Firefox iOS – essentially just Safari with firefox sync, sadly
nowhere near Firefox for Android
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Extensions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://github.com/gorhill/uBlock&quot;&gt;uBlock Origin&lt;/a&gt; – a must, best adblock that exists
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://ublacklist.github.io&quot;&gt;uBlacklist&lt;/a&gt; – already mentioned before, an extension to block LLM
slop from search results in any search engine
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://consentomatic.au.dk/&quot;&gt;Consent-O-Matic&lt;/a&gt; – autofill cookie
banners based on your global preference, a life saver in this day
and age
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Wrap up&lt;/h1&gt;
&lt;p&gt;This article is in no way comprehensive, I only touched on
technologies I have personal experience with. If you have any other
suggestions, feel free to shoot me a message.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;#fn1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; Although if you get a family plan of kagi for 6 people it can
be as $3 per person per month (+ tax)&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#fnref1&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content:encoded></item><item><title>The tale of two *ixs: The Nix and Guix overview</title><link>https://zenmaya.xyz/blog/tale-of-two-ixs-the-nix-and-guix-overview</link><guid isPermaLink="true">https://zenmaya.xyz/blog/tale-of-two-ixs-the-nix-and-guix-overview</guid><description>Many people complain about the accesibily of declarative package management tools, namely Guix and Nix. The problem with sources for the former is a certain assumption of scheme knowledge and with the latter the fragmentation of documentation.
</description><pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Usually people explain Guix/Nix by example, for that I’m afraid you
will have to look elsewhere. I am here to show you the theoretical
overview. Hopefully at the end of this article you will be equipped to
understand Nix and Guix and how they relate to eachother. Even if you
are only interested in one of the two, I implore you to read the whole
article, unless you get very bored and want to stop reading
altogether, as I have written it not with Nix/Guix only reading in
mind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since this article will refer to Guix and Nix a lot, allow me to
refer to them collectively as &lt;em&gt;*ix&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;section&gt;
&lt;h1&gt;What is the store: Wait it’s all hashmaps?&lt;/h1&gt;
&lt;p&gt;First thing a person using *ix hears about is the store. What is it?
Can I buy my drinks there? The store is very similar to what git does.&lt;/p&gt;
&lt;p&gt;The store does not know what packages are, but it can lookup stuff by
an unique identifier, the store is a hashmap. The only difference is
that it is on the filesystem. For the store, there is nothing anywhere
else in the system, just this one hashmap. If we ever want to access
anything else? We need to first put it in the store.&lt;/p&gt;
&lt;p&gt;Usually we have the store in &lt;code&gt;/*ix/store&lt;/code&gt; inside the filesystem.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Deriving a derivation: This literally does not tell me anything&lt;/h1&gt;
&lt;p&gt;Okay so we got a hashmap, but how do we get from A (a package source)
to B (a package binary)? Well my dear reader, that is where
derivations come into play. Derivations are recipies, they take
dependencies, and a build script a and describe the output.&lt;/p&gt;
&lt;p&gt;For this we will take the gnu hello package. It is a simple hello
world package made for showing us how packages are built.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that I have shortened the store paths by replacing the hashes
with &lt;code&gt;...&lt;/code&gt; and formatted it manually, derivations are usually not
this pretty.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;Derive
(
    ## output
    [
        (&quot;out&quot;,&quot;/gnu/store/...-hello-2.12.2&quot;,&quot;&quot;,&quot;&quot;)
    ],
    ## inputs
    [
        (&quot;/gnu/store/...-patch-2.7.6.drv&quot; ,[&quot;out&quot;]),
        (&quot;/gnu/store/...-module-import-compiled.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-coreutils-9.1.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-zstd-1.5.6.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-make-4.4.1.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-file-5.46.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-xz-5.4.5.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-gzip-1.14.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-glibc-2.41.drv&quot;,[&quot;out&quot;,&quot;static&quot;]),
        (&quot;/gnu/store/...-guile-3.0.9.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-tar-1.35.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-linux-libre-headers-6.12.17.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-findutils-4.10.0.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-gawk-5.3.0.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-gcc-14.3.0.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-sed-4.9.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-diffutils-3.12.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-binutils-2.44.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-bash-minimal-5.2.37.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-grep-3.11.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-ld-wrapper-0.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-bzip2-1.0.8.drv&quot;,[&quot;out&quot;]),
        (&quot;/gnu/store/...-hello-2.12.2.tar.gz.drv&quot;,[&quot;out&quot;])
    ],
    ## builder dependencies
    [&quot;/gnu/store/...-module-import&quot;,&quot;/gnu/store/...-hello-2.12.2-builder&quot;],
    ## platform
    &quot;x86_64-linux&quot;,
    ## interpreter
    &quot;/gnu/store/...-guile-3.0.9/bin/guile&quot;,
    ## args
    [
        &quot;--no-auto-compile&quot;,&quot;-L&quot;,
        &quot;/gnu/store/...-module-import&quot;,&quot;-C&quot;,
        &quot;/gnu/store/...-module-import-compiled&quot;,
        &quot;/gnu/store/...-hello-2.12.2-builder&quot;
    ],
    ## env variables
    [
        (&quot;LC_CTYPE&quot;,&quot;C.UTF-8&quot;),
        (&quot;out&quot;,&quot;/gnu/store/...-hello-2.12.2&quot;)
    ]
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So first thing to note that we actually cannot produce gnu hello only
from it’s source code. We need other stuff to build it. The first
obvious thing is gcc, the C compiler, but also other build
tools. To specify dependencies we do not directly refer to the build
dependencies, we would simply loose the information on how were they
produced. We instead refer to their derivations.&lt;/p&gt;
&lt;p&gt;The first argument to our derivation is the name of the output store
item, our compiled package. And as you remember the store only works
with store items so we can’t produce something outside the store.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can see “out” written around every derivation reference, this is
the output specification, as derivations can produce multiple
outputs, but every derivation produces at least “out”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then we take all the dependencies and all the builder
dependencies. This is a Guix build, so the builder is actually guile
code. In Nix it would be a shell script. But there is nothing stopping
us from using a different builder.We can also specify the platform
and the interpreter, it’s arguments and environment variables passed
to the process.&lt;/p&gt;
&lt;p&gt;Now that we have the derivation, we can build it. But oh wait! What if
someone wanted to mess with our store, by changing the contents of a
derivation or the dependency? And how will we know what to build
first? And rust-forbin, we have a race condition?&lt;/p&gt;
&lt;p&gt;This is where the daemon comes in. The daemon is process that has the
sole ownership over the store. We can still access the store items,
but we can’t change them.&lt;/p&gt;
&lt;p&gt;Any time we want to run an operation on the store, we ask the daemon
to perform it on our behalf. Usually this is done through some
RPC. Which means that technically we can just detach the whole store
with the daemon and put there somewhere else, even on the
internet. And that is correct, there are ways to build packages
remotely, and thats one of the advantages of *ix.&lt;/p&gt;
&lt;p&gt;As you may have noticed, the derivation outputs are cached between
multiple calls, so that we don’t have to build the same gcc over and
over. In that regard there is a small issue. What if our binary
depends on the current time or something on disk? We may never
know. So that’s why some care must be taken in order to never build
non-deterministic derivations. If you ever wondered why is every store
item from January 1st 1970, thats why.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Being lazy with derivations: Converting packages to derivations&lt;/h1&gt;
&lt;p&gt;Okay so we can build a derivation easily, but writing them is another
beast. I don’t know about you, but I do not wish to anyone writing
hashes of store items by hand every time. And that is why in *ix we
don’t have to do that. There are some differences though.&lt;/p&gt;
&lt;section&gt;
&lt;h2&gt;Calling package: Hey package!&lt;/h2&gt;
&lt;p&gt;In Nix if we want to create derivation, we usually first need to
construct an standard derivation object. We could directly construct
a derivation with the builtin &lt;code&gt;derivation&lt;/code&gt; but we won’t see that many
plain derivations in the wild today as it has its shortcomings.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;mkDerivation&lt;/code&gt; is the first part of our equation, it allows us to
override some of its parts. The other one is that it already provides
us with a builder script. As we will see shortly it is quite similar
to &lt;code&gt;package&lt;/code&gt; in Guix.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  lib,
  stdenv,
  fetchurl,
}:

stdenv.mkDerivation (finalAttrs: {
  pname = &quot;hello&quot;;
  version = &quot;2.12.2&quot;;

  src = fetchurl {
    url = &quot;mirror://gnu/hello/hello-${finalAttrs.version}.tar.gz&quot;;
    hash = &quot;sha256-...&quot;;
  };

  nativeBuildInputs = [];
  buildInputs = [];

  meta = {
    description = &quot;Program that produces a familiar, friendly greeting&quot;;
    homepage = &quot;https://www.gnu.org/software/hello/manual/&quot;;
    license = lib.licenses.gpl3Plus;
    maintainers = with lib.maintainers; [ stv0g ];
    mainProgram = &quot;hello&quot;;
  };
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every package in Nix is a function, that has some arguments, they are
filled automatically by our call to &lt;code&gt;callPackage&lt;/code&gt; but this means that
we can override them if we desire to do so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;callPackage ./hello.nix {}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;There are actually two attribute functions for every &lt;code&gt;callPackage&lt;/code&gt;
call. These are &lt;code&gt;override&lt;/code&gt; and &lt;code&gt;overrideAttrs&lt;/code&gt;, I can never remember
which is which. &lt;code&gt;override&lt;/code&gt; is for changing the function arguments
passed to the function and &lt;code&gt;overrideAttrs&lt;/code&gt; is for changing the
attributes of the &lt;code&gt;mkDerivation&lt;/code&gt;. We call them as follows
&lt;code&gt;(callPackage ./hello.nix {}).override&lt;/code&gt; or &lt;code&gt;[...].overrideAttrs&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Package to derivation: Wait what is a package?&lt;/h2&gt;
&lt;p&gt;Guix is very similar to Nix in how it specifies packages. There is
some difference in that Nix works only with derivations, but Guix
preserves the package record as long as possible, so you pass around
lists of packages.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(define-public hello
  (package
    (name &quot;hello&quot;)
    (version &quot;2.12.2&quot;)
    (source (origin
              (method url-fetch)
              (uri (string-append &quot;mirror://gnu/hello/hello-&quot; version
                                  &quot;.tar.gz&quot;))
              (sha256
               (base32
                &quot;...&quot;))))
    (build-system gnu-build-system)
    (synopsis &quot;Example GNU package&quot;)
    (description &quot;...&quot;)
    (home-page &quot;https://www.gnu.org/software/hello/&quot;)
    (license gpl3+)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other difference you may have noticed is the &lt;code&gt;build-system&lt;/code&gt;
field. It specifies the builder script, in Guix its in Guile, that
will build this package. It also contains some dependencies.&lt;/p&gt;
&lt;p&gt;If we wanted to realize package manually, we can call
&lt;code&gt;package-&amp;gt;derivation&lt;/code&gt; to convert the package to the derivation.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;100 gexps: The guix aside&lt;/h2&gt;
&lt;p&gt;In Nix we can specify derivation inputs by string substitutions. But
in Guix we have a more elegant system. It’s called Gexps, it stands
for Guix-Expressions and they function similarly to &lt;code&gt;quote&lt;/code&gt; and
&lt;code&gt;unquote&lt;/code&gt;. We usually write them as &lt;code&gt;#~&lt;/code&gt; and &lt;code&gt;#$&lt;/code&gt; Gexps are records
that hold all the info needed to build a derivation. Let’s look at an
example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#~(begin
    (mkdir #$output)
    (chdir #$output)
    (symlink (string-append #$coreutils &quot;/bin/ls&quot;) &quot;list-files&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we evaluate the expression we receive this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;∫ guix repl
scheme@(guix-user)&amp;gt; (use-modules (guix gexp))
scheme@(guix-user)&amp;gt; (use-modules (gnu packages base))
scheme@(guix-user)&amp;gt; #~(begin
    (mkdir #$output)
    (chdir #$output)
    (symlink (string-append #$coreutils &quot;/bin/ls&quot;) &quot;list-files&quot;))
$1 = #&amp;lt;gexp (begin (mkdir #&amp;lt;gexp-output out&amp;gt;) (chdir #&amp;lt;gexp-output out&amp;gt;) (symlink (string-append #&amp;lt;gexp-input #&amp;lt;package coreutils@9.1 gnu/packages/base.scm:471 7f34089412c0&amp;gt;:out&amp;gt; &quot;/bin/ls&quot;) &quot;list-files&quot;)) 7f340a1cdc00&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;We can access previously evaluated values with the &lt;code&gt;$n&lt;/code&gt; syntax, it
reduces the noise in this article quite a bit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As we can see, the what we got back is the gexp record. And if we
evaluate it, we get a derivation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scheme@(guix-user)&amp;gt; (use-modules (guix store))
scheme@(guix-user)&amp;gt; ((gexp-&amp;gt;derivation &quot;example&quot; $1) (open-connection))
$2 = #&amp;lt;derivation /gnu/store/...-example.drv =&amp;gt; /gnu/store/...-example 7f34160212d0&amp;gt;
$3 = #&amp;lt;store-connection 256.100 7f24b6ddf5a0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;gexp-&amp;gt;derivation&lt;/code&gt; function returns a function that takes the
connection to the store and realizes the derivation. The
&lt;code&gt;(open-connection)&lt;/code&gt; is just opening a socket to RPC the daemon. This
has actually put the derivation into the store, but it hasn’t yet run
the build code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scheme@(guix-user)&amp;gt; (use-modules (guix derivations))
scheme@(guix-user)&amp;gt; (derivation-file-name $2)
$4 = &quot;/gnu/store/...-example.drv&quot;
scheme@(guix-user)&amp;gt; (build-things $3 (list $4))
$5 = #t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The builder itself does not understand the derivation record, so we
need to first get the derivation file name from it and only then we
can build it.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Inputs: Why are there so many inputs?&lt;/h2&gt;
&lt;p&gt;When specifying dependencies one could not be blamed for confusing
what is what. There are so many input variants and the names differ
between Nix and Guix, so here is a table for translation:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;host platform&lt;/th&gt;
&lt;th&gt;target platform&lt;/th&gt;
&lt;th&gt;guix&lt;/th&gt;
&lt;th&gt;nix&lt;/th&gt;
&lt;th&gt;example&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;build&lt;/td&gt;
&lt;td&gt;build&lt;/td&gt;
&lt;td&gt;native-inputs&lt;/td&gt;
&lt;td&gt;depsBuildBuild&lt;/td&gt;
&lt;td&gt;autotools, bison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;build&lt;/td&gt;
&lt;td&gt;host&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;nativeBuildInputs&lt;/td&gt;
&lt;td&gt;compilers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;build&lt;/td&gt;
&lt;td&gt;target&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;depsBuildTarget&lt;/td&gt;
&lt;td&gt;&lt;em&gt;rarely needed&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;host&lt;/td&gt;
&lt;td&gt;host&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;depsHostHost&lt;/td&gt;
&lt;td&gt;metaprograms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;host&lt;/td&gt;
&lt;td&gt;target&lt;/td&gt;
&lt;td&gt;inputs&lt;/td&gt;
&lt;td&gt;buildInputs&lt;/td&gt;
&lt;td&gt;libraries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;target&lt;/td&gt;
&lt;td&gt;target&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;depsTargetTarget&lt;/td&gt;
&lt;td&gt;&lt;em&gt;rarely needed&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;*ix allows for cross-compiling to different architectures,
ie. x86-&amp;gt;arm etc. For that it differentiates between different
platforms, the host platform is the dependency’s platform it should be
running on, and the target platform is the platform the derivation is
building towards.&lt;/p&gt;
&lt;p&gt;On Guix if we would want to have something like &lt;code&gt;build-&amp;gt;host&lt;/code&gt;
compiler, we tell Guix and it solves it automatically by building a
cross copiler in the background.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Phases: Okay so what to do now?&lt;/h2&gt;
&lt;p&gt;Phases allow you to control and schedule code snippets in between
other parts of the builder code. In guix these are heavily dependent
on the build system, and I sadly have to say, you will have to check
the source code. Not to mention that they can derive from other build
systems so always check your builder as well as the gnu builder.&lt;/p&gt;
&lt;p&gt;As for Nix, it isn’t much better, but at least some of them are in the
nixpkgs reference manual.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Conclusion: Part two?&lt;/h1&gt;
&lt;p&gt;Originally I intended to include the Nixpkgs module system and Guix
services here, but this article is already quite long enough, so it
will have to come next time. I hope you learned something here, I have
been using *ix for a few years now and realized that I am one of the
small group that can actually talk about both systems and compare
them. Not to toot my own horn, if you find any mistakes in the article
feel free to reach out.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h1&gt;Appendix: Useful resources&lt;/h1&gt;
&lt;section&gt;
&lt;h2&gt;Nix&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://nixos.org/manual/nixpkgs/unstable&quot;&gt;Nixpkgs reference
manual&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://wiki.nixos.org/&quot;&gt;NixOS wiki&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://jade.fyi/&quot;&gt;jade’s blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://github.com/NixOS/nixpkgs&quot;&gt;Nixpkgs source code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2&gt;Guix&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&quot;https://guix.gnu.org/manual/devel/en&quot;&gt;Guix manual&lt;/a&gt; - I love the
single huge HTML one just because I can &lt;code&gt;C-f&lt;/code&gt; across it.
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://guix.gnu.org/cookbook/en/&quot;&gt;Guix cookbook&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&quot;https://codeberg.org/guix/guix&quot;&gt;Guix source code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content:encoded></item></channel></rss>