1. 4

    Great post.

    The word ‘user’ invokes the idea of manipulation, of addiction. It suggests that people need this product without referencing the product’s responsibility to do right by them.

    One thing that I find hysterically funny is that the only other place the term user is widely used is in reference to illegal drugs. Meth, coke, heroin, these things all have users.

    Even if I don’t have a specific term for the people a product should serve yet, I say “constituents” instead of ‘users.’ This word choice reverses the role of dependence.

    This gets to the heart of why people feel that the term user is demeaning. It is demeaning in the same way that governments calling their citizens consumers is demeaning.

    1. 3

      Relatedly, I’ve ran qemu from a rescue disk, passing the hard drive from an installed system as a disk device. It’s a lovely way to poke at and debug a borked installation if you’re blind. I.E., if the TTS software doesn’t start when the installation is booted on bare metal, boot to rescue and boot the install under qemu in order to debug the boot process accessibly.

      1. 33

        Projects should use alternative networks, like OFTC or Libera, or better yet, operate their own IRC infrastructure. Self-hosting is really what makes IRC great: you can run your own server for your community and not be beholden to anyone else.

        Self-hosting IRC is not such a great notion.

        I know someone who hosts a small-time IRC network of two servers (two for redundancy). I doubt there are more than 40 people on it. When I was there a couple weeks back, it was being attacked by spam bots.

        I host an IRC server for a few friends and family. The reason it has worked as well as it has is that the server has a minimal and heavily restricted configuration. You don’t get onto that server unless you know somebody who is already there. I’d really love to replace it with some XMPP conferences or something, but getting buy-in from all my users isn’t so easy.

        Having lots of tiny IRC servers (or networks) is also inconvenient from a configuration point of view, as you need to add an entry for each network to a client config and most likely a bouncer config as well. And then you probably need to establish credentials for yet another service on the net.

        IRC wasn’t meant to be used in a fully decentralized way like that. For fully decentralized, the better bet is XMPP, or perhaps Matrix (though I don’t have much experience with the latter).

        If you’re going to use IRC for a project, please by all means use Libera or OFTC.

        I, too, am sad to see what happened to Freenode. I met my girlfriend there, and we’ve been together for 10 years as of this month. She was Freenode staff, and our first encounter involved her chewing me out for some minor policy infraction. She doesn’t remember it, but I sure do. It was the one and only time I got called out for something by staff. Two years later we were formally introduced.

        I was surprised to see a mention of Freenode Radio. She was involved with that too, and she saved a bunch of her recordings.

        I was heartbroken by the Freenode takeover. I dropped my nickserv account and left about an hour after the staff exodus.

        1. 4

          Holy cow yes this. I saw this and did a double take!

          Running a sizable open source project is a LOT of work. I can’t even wrap my head around it honestly. Asking maintainers to run their own IRC server feels like a TON of extra work with very little actual gain.

          Also, mightn’t it be time to move on from IRC? I get that Discord and Slack represent proprietary monied interests which one might wish to avoid, but what about Matrix as others have said?

          1. 4

            Also, mightn’t it be time to move on from IRC? I get that Discord and Slack represent proprietary monied interests which one might wish to avoid, but what about Matrix as others have said?

            IRC is time-tested and it mostly “just works”. I don’t have a whole lot of incentives to move to Matrix, and I possibly even have some disincentives. Text chat is a sweet spot for me. Being blind, adding things like images to chat brings me nothing and in fact often cuts me out of communication entirely. But we’ll ignore that issue for now, because I agree, IRC has some real rough edges.

            I also don’t see what Matrix brings to the table that we can’t already have with XMPP. XMPP is a time-tested protocol specified by actual RFCs, with a well-functioning extension process (XEPs). There is a profusion of compatible implementations. What does Matrix get me that XMPP doesn’t? I’m willing to be convinced, because I do think we need a widely-deployed protocol for chat and messaging that can replace IRC.

            1. 2

              I’m glad IRC works for you. That’s fantastic. i’m partially blind myself so I can definitely appreciate how the bling can get in the way (although I can at least see it and don’t need to deal with the garbage a screen reader likely spews when it hits a dancing bear).

              One key advantage I see Matrix as having is persistence.

              Yes, you can set up an IRC bouncer, but maintaining infrastructure to run same said is a pain, and Matrix gives that to me for free.

              Anyway, use what you like. IRC clearly isn’t going anywhere, I just find myself never getting there because I have to think about firewalls, and connectivity, and persistence, Aaaaaand…….

              60 things come into my queue and any thought of futzing with Ye Olde Fashioned IRC goes out the window

            2. 2

              My co-maintainer set up a channel with gitter.im which is basically matrix at this point, I think. I’m not sure how easy it was to set up, but it’s been hassle-free to administer and integrates nicely with the terminator github repos

            3. 1

              How about running a Matrix server? I currently run my own Matrix instance and am on a few dev rooms (peertube, synapse-dev and others). Matrix absorbed Gitter a while back and has a lot of those developer rooms as well.

            1. 10

              From A Scheme Shell, by Olin Shivers:

              Shell programming terrifies me. There is something about writing a simple shell script that is just much, much more unpleasant than writing a simple C program, or a simple CommonLisp program, or a simple Mips assembler program. Is it trying to remember what the rules are for all the different quotes? Is it having to look up the multi-phased interaction between filename expansion, shell variables, quotation, backslashes and alias expansion? Maybe it’s having to subsequently look up which of the twenty or thirty flags I need for my grep, sed, and awk invocations. Maybe it just gets on my nerves that I have to run two complete programs simply to count the number of files in a directory (ls | wc -l), which seems like several orders of magnitude more cycles than was really needed.

              I liked the example in the article, but we can also use it to show the shortcomings of Unix philosophy. Suppose we wanted to roll a 10-million-sided die (I.E., pick an integer between 1 and 10000000). Here’s what that looks like in terms of computing efficiency.

              $ time ( seq 1 10000000 | shuf | head -n1 )
              real	0m6.966s
              user	0m6.423s
              sys	0m1.277s

              I ran that on my Raspberry Pi because it was a good demonstration. It’s faster on x86 systems: 2.5 seconds on a 2012-era AMD CPU, and 1.4 seconds on an Epyc Rome system from 2020.

              If we wanted to roll a 2**64-sided die, forget about it.

              In practice, what you do in Unix philosophy is write a C program called randrange or similar, adding a new verb to your language.

              Another point: one thing that makes Unix philosophy attractive is the compositionality. Compositionality is what some of us love about Forth (I’m an ex-Forther). The difficulty with both is “noise” that obscures solutions to problems. In Forth, the noise is stack juggling. In Unix, it is all the text tool invocations that massage streams of data.

              1. 20

                On the contrary that one is ultra fast:

                % time env LC_ALL=C tr -c -d '0-9' < /dev/random | head -c 7
                env LC_ALL=C tr -c -d '0-9' < /dev/random  0.01s user 0.01s system 95% cpu 0.016 total
                head -c 7  0.00s user 0.00s system 32% cpu 0.009 total
                1. 8

                  In gnu land:

                   time shuf -i 0-10000000 -n1
                  real	0m0.005s
                  user	0m0.002s
                  sys	0m0.002s

                  1 command, and it’s super fast.

                  -i equald the range to select from and -n equals the number of items to return.

                  1. 3

                    The shuf(1) can also be installed on FreeBSD from packages.

                    On my 10 years old system:

                    % time shuf -i 0-10000000 -n1
                    shuf -i 0-10000000 -n1  1.02s user 0.02s system 99% cpu 1.041 total
                    % pkg which $( which shuf )
                    /usr/local/bin/shuf was installed by package shuf-3.0
                    1. 2

                      Awesome! I didn’t have a BSD machine readily available, and I don’t remember the shuf details, so I didn’t want to claim it would work there. The shuf on the system I used is from GNU coreutils 8.32.

                      It seems like the BSD shuf at least in version 3.0, it actually is generating the full 10000000, since it’s taking 1s and 99% CPU.

                      The GNU version seems to skip that step, since it takes basically no time. I wonder if newer versions of BSD’s shuf also take that shortcut.

                      1. 3

                        Seems that is little more complicated :)

                        The shuf(1) I used in the above example is from sysutils/shuf package - which is:

                        “It is an ISC licensed reimplementation of the shuf(1) utility from GNU coreutils.”

                        I also have sysutils/coreutils installed and gshuf(1) from GNU coreutils [1] is a lot faster (like Your example):

                        % time gshuf -i 0-10000000 -n1
                        gshuf -i 0-10000000 -n1  0.00s user 0.00s system 63% cpu 0.005 total

                        [1] The GNU coreutils on FreeBSD have additional ‘g’ letter in from of them to avoid conflicts - like gshuf(1)/gls(1)/gtr(1)/gsleep(1)/… etc.

                        Hope that helps :)

                        1. 1

                          My question was, if newer versions of


                          also had the ability to skip creating the full range, if only 1 output was requested. At least that’s my assumption on why GNU shuf is 1s faster than the copy from sysutils/shuf

                          Otherwise I agree with everything you said, obviously.

                          1. 1

                            As I see here - https://github.com/ibara/shuf the sysutils/shuf port is at current 3.0 version.

                            There is no newer 3.1 or CURRENT version of this ISC licensed shuf(1).

                            1. 1

                              Sorry, I apologize. I assumed there was likely a new version since you mentioned:

                              On my 10 years old system:

                              way back up there somewhere.

                              Have an awesome day!

                              1. 1

                                The 10 years old system referred to my oldschool ThinkPad W520 hardware :)

                                The system is ‘brand new’ FreeBSD 13.0-RELEASE :)

                                You too, thanks.

                  2. 2

                    I do find this interesting but at the same time I think it’s missing the point. I’m sure this comment was not intended to be and actually is not one of those clever “yes but what’s performance like” throwaway comments at meetings, but I wanted to pick up on it anyway.

                    One thing that the spectrum of languages has taught me is that there are different jobs and different tools for those jobs. The point that I saw from the example was composability and STDIO pipelining, with an example simple enough not to get in the way of that for newcomers.

                    You say “in practice”, directly after having just wondered about a 10-million sided die. Such an object, at least in my experience, is not something you come across in practice. As an ex D&D gamer, anything more than 20 sided is extreme for me and I suspect for most people.

                    1. 2

                      One thing that the spectrum of languages has taught me is that there are different jobs and different tools for those jobs.

                      It’s true.

                      The point that I saw from the example was composability and STDIO pipelining, with an example simple enough not to get in the way of that for newcomers.

                      Oh no, I didn’t miss the point at all. I wasn’t criticizing the example; I think it is a good one that demonstrates Unix philosophy quite well. I was making a counter-point, that with Unix philosophy, sometimes the specific solution does not generalize.

                      Another point worth making is that a solution involving pipes and text isn’t necessarily the correct one. For instance, consider the classic pipeline to count files in a directory: ls |wc -l. I use that all the time. The only reason it almost always gives correct answers is that by custom, nobody puts newlines in filenames, even though it is totally legal.

                      mkdir /tmp/emptydir
                      cd /tmp/emptydir
                      fname="$(printf "foo\nbar")"
                      touch "${fname}"
                      ls |wc -l

                      That gives the answer 2. So much for counting files with wc.

                      You say “in practice”, directly after having just wondered about a 10-million sided die. Such an object, at least in my experience, is not something you come across in practice.

                      It was a whimsical use of metaphor, though maybe God plays D&D with 2**64-sided dice? The problem of picking a random integer in the range 1 to X comes up frequently enough that Python has a function in its standard library for it: random.randrange.

                    2. 2

                      If we wanted to roll a 2**64-sided die, forget about it.

                      $ time env LC_ALL=C tr -cd a-f0-9 < /dev/urandom | head -c 16
                      env LC_ALL=C tr -cd a-f0-9 < /dev/urandom  0.00s user 0.00s system 68% cpu 0.012 total
                      head -c 16  0.00s user 0.00s system 34% cpu 0.009 total
                    1. 4

                      Classic Linux distros just aren’t made for the casual user, but that’s ok. I don’t think they should be. Sharp tools require a willingness to invest time in learning them. Not everyone can do that, and not everyone who can do so would actually want to. So let’s forget about desktop Linux and relegate that tired phrase to the dustbin of history.

                      A more interesting goal would be a desktop appliance powered by free software, and I think the way you might get it right now is to start with Lineage or one of the other AOSP builds. There’s literally a free software powered appliance computer ready to happen; someone just needs the wherewithal to make it. Suppose, a commodity x86 system running an OS derived from AOSP, perhaps with a Windows emulation layer for running legacy proprietary Windows applications?

                      1. 1

                        Perhaps having Wine and such running on Haiku?

                        Much as I love Linux and for what it’s achieved, “the little kernel that could”, I’m done with some aspects of it and wish it could be replaced on the desktop.

                        Haiku must be the little desktop OS that actually puts up a fight, but it can’t unless it runs 100% of the Linux apps.

                        1. 2

                          The thing with Haiku is the development is so… random? People just pick up projects, maintain them for a bit, go do something else. It’s not a very structured development environment to base the future of desktop computing on.

                          1. 2

                            Lost my reply… All this just feels like a sad state of affairs cuz Linux is hard to fix for the desktop, especially for the mostly useless Unix features, and the only one who kinda did it is Apple :/

                        2. 1

                          Suppose, a commodity x86 system running an OS derived from AOSP, perhaps with a Windows emulation layer for running legacy proprietary Windows applications?

                          Win32 is the Linux stable ABI. I suspect you’d get OS/2’d pretty quickly.

                        1. 5

                          Also, why would you trust them more with collecting your IP than google?

                          Because Google has repeatedly demonstrated that it doesn’t deserve my trust. To Google, the data collected about me is a goldmine, not a liability. Users of a free Google property are the commodity in which Google trades. The customers are the people selling ads. It’s old well-explored territory.

                          I also fail to see how an IP address would be a useful metric for Audacity. Maybe knowing whether it is IPv6 or IPv4 could be useful, but that’s about it.

                          Audacity deserves some kudos for making it opt-in and being open about what they’re doing. I can’t really find fault here. Good on them for being transparent and opt-in.

                          1. 2

                            I also fail to see how an IP address would be a useful metric for Audacity

                            This also strikes me as odd. If they want to really track for people that are using it for a longer time it fails the moment you use mobile data or get the daily connection reset from your ISP. If they just want to see when the same user does something in a span of 1-2 hours it might work. But that’s already very detailed. And a typical CG NAT will prevent any identification. Though maybe that’s fine for them if they want crash reports and some hardware statistics.

                          1. 2

                            The earlier Bertrand Meyer submission reminded me of this little forgotten gem from Usenet.

                            1. 12

                              using declarative unit files similar to systemd,

                              I’m not a huge systemd opponent, but the reason I dislike it enough to have an opinion are the unit files. The language is neither flexible nor intuitive enough to be guessed, nor do I use it often enough to memorize it. That means whenever I want to create a new service or timer or whatever, I have to deal with onscure documentation or copy-paste-tweak some code from arch wiki or stack overflow. A system like runit is attractive (though not technically superior) because all I need is to write my command in a file named “run”.

                              I hope that Alpine’s alternative will make improvments on this front, be it by providing better tooling or by improving the language. Ideally it should be able to parse systemd unit files but allow these to be degenerated as much as possible, allowing lazy users to only write as much as neccesary.

                              1. 8

                                I find the systemd documentation pretty straight-forward and very well written, so I’m surprised that you find it obscure :)

                                The man pages are my go to for anything related to systemd, and examples of all kinds of systemd units, including timers, are plentiful and already installed on my laptop:

                                $ systemctl list-units --type timer 
                                  UNIT                           LOAD   ACTIVE SUB     DESCRIPTION                                                    
                                  anacron.timer                  loaded active waiting Trigger anacron every hour                                     
                                  apt-daily-upgrade.timer        loaded active waiting Daily apt upgrade and clean activities                         
                                  apt-daily.timer                loaded active waiting Daily apt download activities                                  
                                  e2scrub_all.timer              loaded active waiting Periodic ext4 Online Metadata Check for All Filesystems        
                                  fstrim.timer                   loaded active waiting Discard unused blocks once a week                              
                                  fwupd-refresh.timer            loaded active waiting Refresh fwupd metadata regularly                               
                                  logrotate.timer                loaded active waiting Daily rotation of log files                                    
                                  man-db.timer                   loaded active waiting Daily man-db regeneration                                      
                                  motd-news.timer                loaded active waiting Message of the Day                                             
                                  systemd-tmpfiles-clean.timer   loaded active waiting Daily Cleanup of Temporary Directories                         
                                  update-notifier-download.timer loaded active waiting Download data for packages that failed at package install time 
                                  update-notifier-motd.timer     loaded active waiting Check to see whether there is a new version of Ubuntu available
                                  zsys-gc.timer                  loaded active waiting Clean up old snapshots to free space                           
                                LOAD   = Reflects whether the unit definition was properly loaded.
                                ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
                                SUB    = The low-level unit activation state, values depend on unit type.
                                13 loaded units listed. Pass --all to see loaded but inactive units, too.
                                To show all installed unit files use 'systemctl list-unit-files'.
                                $ systemctl cat apt-daily.timer 
                                # /lib/systemd/system/apt-daily.timer
                                Description=Daily apt download activities
                                OnCalendar=*-*-* 6,18:00

                                Once in a while I find a systemd keyword used in units that I can’t find the documentation for, but luckily man can be used for this purpose too:

                                $ man -wK defaultdependencies

                                I remember the #systemd channel on Freenode as pretty active, so if you’re stuck consider asking there.

                                1. 4

                                  Maybe obscure it the wrong word, but as I say, as someone who only deals with systemd directly once or twice a year,

                                  $ man -k systemd | wc -l

                                  is a first step I have to make every time.

                                  Just a few months ago I wanted to create a timer, to replace a user cron job, but the number of concepts I have to read up on before I write anything seems like it’s not worth it.

                                  Maybe this is just a mindset thing, *nix is certainly not obvious when you first start, but you gain an intuition over time and can start guessing how to do things. Systemd doesn’t play into this intuition.

                                  1. 3

                                    Completely understand what you mean – the increasing complexity of computers and the layers upon layers of abstraction is definitely an issue. I deal with systemd unit files fairly often, so I’ve internalized much of the knowledge and feel that systemd units behave pretty much like I expect them to.

                                    Much of it probably comes down to systemd simply being different from what we’ve used in the past – sysv style init, cron daemons etc. However even though I’ve used Linux for almost two decades and I’ve written plenty of cron jobs I still find myself looking at the man page to decipher the cron timer values. In that regard I do find systemd a lot more sane – the unit files themselves are much more readable than both cron jobs and sysv style init scripts, not at least because they’re more verbose, and the documentation is really good.

                                    1. 1

                                      However even though I’ve used Linux for almost two decades and I’ve written plenty of cron jobs I still find myself looking at the man page to decipher the cron timer values. In that regard I do find systemd a lot more sane

                                      Yes, but the difference I was implying is that (at least on my systems), crontabs start with a comment reminding you of the syntax with a few examples. That kind of approach is missing in systemd. Maybe a simple interactive create-service shell script could fix this issue.

                                2. 3

                                  Agree that the unit file language is not terribly good. In terms of strings and paths and stuff it’s just enough like bash to trip you up, and then you say “fuckit” and write a bash script that gets called by the unit file and now it’s no longer declarative. Its reading of environment variable files is similarly not-quite-what-you-expect. The combinations of options, dependencies and pre/post/during choices for units is not exactly the most elegant or intuitive, by a long shot. It works, but only once you understand every single option in isolation and can pick and choose the right ones. It is the exact opposite of the delight you feel when you say “okay, option X must exist, and it’s probably called X…” and discover you are correct.

                                  1. 2

                                    I’m sort of neutral about systemd, but I do like the unit files. I have some of the same problems as you do when writing a unit file from scratch. Systemd is well-documented, but there are so many knobs that it can be hard to find exactly what you want. I think it is a tooling problem.

                                    If I were working with systemd on a daily basis, I’d probably try my hand at writing a small unit file generator. I’ve used ansible to generate .service files from a Jinja template. That takes care of a lot of rote, boiler-plate stuff. My point is there are 90% solutions that would make things more pleasant.

                                    1. 1

                                      Taking the same language and providing better infrastructure around creating them would suffice in 99% of cases. After all, runit would be enough for most people most of the time anyway.

                                    1. 1
                                      • Getting my first covid poke on Thursday!
                                      • Working on setting up mycroft.ai in a VM.
                                      • Possibly converting a web server from Linux to FreeBSD. I want some experience administering FreeBSD, particularly with using jails.
                                      • Figuring out how to flash a Keyboardio Atreus with QMK. Actually most of the figuring out is done, and it is about time for the doing of the deed.
                                      • Setting up a gitbucket instance for experimentation and potential adoption. A friend uses that and speaks well of it.
                                      1. 5

                                        A reminder that the term “open source” was coined by the “anarcho”-capitalist Eric Steven Raymond to replace “free software”, because the term was – and is – unpalatable to capitalists. I made a deliberate choice to stop saying “open source” a year or two ago, because calling it “open source” is an invitation to exploitation.

                                        First, we had conglomerates strip-mining it like yet another resource. And now, we have unethical researchers experimenting on random unsuspecting volunteers without even a fig leaf of consent. Enough is enough.

                                        1. 8

                                          This is only a bad thing if you hold the political position that anarcho-capitalism, or capitalism broadly speaking, are bad. If you don’t hold this political position than this is not a reason to avoid using the term “open source”. ESR himself has written on several occasions about how and why the term “open source” was coined and initially popularized by him and several colleagues - he describes the decision as one of “marketing” and “branding”, that is, part of the art of convincing large numbers of other humans to do something, which is a pre-capitalist concept.

                                          In any case, public universities are not capitalist institutions - they are funded by the state out of taxpayer funds based on the political decision that running university-like institutions is broadly good for citizens. Academic researchers working for such institutions, whether they act ethically or unethically with respect to any ethical system, are not acting as capitalists while doing their research.

                                          Bringing up capitalism with respect to this event actually strikes me as particularly irrelevant - the core issue here is that some security researchers tried to submit malicious packages to a particular important open-source project, in order to test how good the open-source development process of the Linux kernel was at detecting attempts to submit malicious code. People might try to get malicious code into the Linux kernel for any number of reasons - because they are capitalists who wish to use malicious code in the kernel to harm other capitalists using Linux; or harm the idea of free software; or because they are government agents or NGOs or informal political actors trying to accomplish some act of sabotage; or perhaps because they have a personal grudge against another kernel maintainer. I personally was amused by the idea that this incident was itself a “bona fide” attempt to put malicious code into the kernel, and claiming to be computer security researchers doing an unauthorized pentest was itself a cover story.

                                          1. 5

                                            The relevance of capitalism to this particular case is indirect rather than direct. My point is that rebranding to open-source deemphasized other values, like community or user freedom.

                                            And the end result has been exploitation, be it from companies looking to strip-mine a software commons, HR departments treating github as a CV, unethical researchers treating Linux developers as lab rats, and so on. What these things all have in common is exploitation, rather than capitalism per se. My point is that the rebranding and the exploitation are linked.

                                            1. 5

                                              They’re really not linked though - nothing about this incident would’ve worked any differently if people called the Linux kernel “free software” rather than “open source software”. In fact, these terms are basically identical in meaning and people do routinely use both terms to talk about the Linux kernel all the time. For that matter, researchers performing an unauthorized social engineering attack on the Linux kernel maintainers is a failure mode that really has little to do with the other software-related social phenomena you mention, whose status as problems is dependent on the political ideology of the person judging them.

                                          2. 7

                                            And a reminder that ESR did not “coin” the term “open source” (Christine Peterson did), and that the God-Emperor of Free Software – Richard Stallman – is a self-described capitalist who encourages software developers being able to profit from their towk.

                                            1. 2

                                              One could certainly be forgiven for concluding that Raymond invented it after reading this and similar. There is no mention of Christine Peterson on that page.

                                              and that the God-Emperor of Free Software – Richard Stallman – is a self-described capitalist

                                              No gods, no masters! At the end of the day, I don’t give a rusted counterfeit nickel about what RMS or a lot of other people think; I make up my own mind.

                                          1. 1

                                            How does this differ to the currying syntax that some schemes provide directly in define or lambda (https://srfi.schemers.org/srfi-219/)?

                                            1. 4

                                              Yes, a lot of schemes provide directly in a lambda or define the ability to make something like this:

                                              (define (((foo bar) baz) bax) (+ bar baz bax))

                                              That is an amazing construct, I’m into it, I’m happy Scheme can do it.

                                              I made a post here about that type of curry a month ago and a comment about that type of curry an hour ago.

                                              What I’ve made here is more awesome in the following way.

                                              With (define (((foo bar) baz) bax) (+ bar baz bax)), you have to predict the arities exactly.

                                              Sure, you can do

                                              (map (lambda (proc) (proc 500)) (map (foo 3) '(10 20 30)))

                                              and get (513 523 533).

                                              But with the define-curry I’ve made here, if you do

                                              (define-curry (foo bar baz bax) (+ bar baz bax))

                                              Not only does the above map work (and give the same (513 523 533) result). You can curry any of the arguments. All or none or just some.

                                              (define (((foo bar) baz) bax) (+ bar baz bax)) means that you predict that you are gonna add on one argument first, and then the other, and then the other.

                                              Or you might want to take two arguments first and only leave one argument hanging: (define ((foo bar baz) bax) (+ bar baz bax)) or you might want to take one argument first and leavet two arguments hanging: (define ((foo bar) baz bax) (+ bar baz bax))

                                              You have to know before. The procedures aren’t flexible at all.

                                              With (define-curry (foo bar baz bax) (+ bar baz bax)), you can call foo with any number of arguments and it’ll wait for the rest.

                                              You can even use it like any normal procedure and do (foo 10 200 3) right away to get 213. Or you can do (foo 10 200) and wait for the last number, or (foo 10) and wait for the last two numbers. And if you do, you can even then only give it one and keep waiting even more on that last number .You get a procedure that’s ready for anything!

                                              That’s what I mean by arbitrary-arity, level-recursive currying.

                                              That’s why my example was:

                                               (foo 100 20 3)
                                               ((foo 100) 20 3)
                                               ((foo 100 20) 3)
                                               ((foo) 100 20 3)
                                               (((foo) 100) 20 3)
                                               (((foo 100) 20) 3)
                                               ((((foo) 100) 20) 3))

                                              All those forms evaluate to the same thing! That’s the baller part! And (((foo) 100 20) 3) also or for that matter (((((foo)) 100)) 20 3).

                                              This is great, all those times I’ve used a procedure and been like “aw, man, I wish this was curried!”

                                              If it had been curried (using the SRFI-219 style curries), that would’ve gotten obnoxious quickly too, because I would’ve had to add in those extra parens everytime I didn’t need the curry feature. I would’ve had to always write ((((foo) 100) 20) 3) or whatever the procedure-writer predicted I was gonna need to write.

                                              That’s why this is awesome.

                                              Now to the bonus episode. The define-curry I made is great when defining new procedures but what about all the backlog of existing procedures? Like + and print and list. I don’t wanna be bothered to re-define all of them with define-curry, I want to be able to use them and curry them as they are. That’s why I made 🍜 (yeah, combinators and operators can be or contain emoji in Chicken Scheme).

                                              I just prefix any function with 🍜 and it gains one level of arbitrary arity curry. (🍜 list 1 1 2 3 5) becomes a procedure that waits for more arguments to add to the list, so

                                              ((🍜 list 1 1 2 3 5) 8 13 21 34)

                                              (1 1 2 3 5 8 13 21 34).

                                              This is worse than the define-curry I made at the top of the post in the sense that it only gives me one level of calls / parens. If I need more levels, I need to add more 🍜.

                                              ((🍜 (🍜 list 1 1 2 3 5) 8 13) 21 34)

                                              (1 1 2 3 5 8 13 21 34).

                                              On the other hand, one part of the 🍜 combinator that is better than my define-curry is that it can handle procedures that themselves are already arbitrary-arity, like list and + and string-append. The define-curry only works with procedures that have a specific number of arguments. (In the case of the foo example, three arguments and it always adds three numbers.) Also, again, that it works on already existing procedures, not just newly defined ones.

                                              1. 3

                                                This is a cool post on multiple levels. As an ocaml fan, it’s fun reading about currying in Scheme. And kudos for 🍜 as an identifier! Functional programming, food, and puns: three of the good things in life.

                                                1. 2

                                                  It feels like The Little Schemer for 2021.

                                                2. 2

                                                  I don’t understand why the ramen emoji was chosen when there’s a perfectly good curry with rice emoji 🍛

                                                  1. 1

                                                    Because I didn’t know about it! Post now updated to use 🍛, thank you!♥

                                                    Trying to making that change over SSH (which I failed to do, I had to get up and go to the desktop) reminded me that it’s probably better to use some other identifier for this combinator. Maybe just a letter, k or h or c or something. I originally wanted to make read-syntax, some special kind of parentheses or something for this.

                                              1. 4

                                                There is a third dimension that his analysis is lacking: persistence, the quality of being available for long durations without human intervention. A ticket comment system is maximally persistent. A wiki may be persistent. A centralized, searchable email list is maximally persistent, but personal email conversations may be quite transient. Some chat systems are searchable and persistent, some are terrible at making history presentable.

                                                1. 3

                                                  My preference is an issue tracker with excellent email integration. Everyone gains.

                                                  At my last job we used RT, and most of my ticket-tracking workflow was through email. RT provided organization, mediation, and long-term storage. I loved it.

                                                  1. 1

                                                    My team (IT and Ops) uses RT for issue tracking, but the dev groups have insisted on JIRA for a while. We’ll need to get them over to something else in a couple of years, since self-hosted JIRA is going away.

                                                    1. 3

                                                      That’s really weird, I’ve never seen an org where the devs have preferred JIRA over anything, it’s always been PM and management.

                                                  2. 1

                                                    The Dovecot project runs a public read-only IMAP server for their mailing list archives. In theory, this is great because you can just add that server and then reply to threads and messages before you joined the list. In practice, the UI for this kind of thing is terrible in most mail clients and is even worse when you consider multiple clients and wanting to be able to access it from your desktop / laptop / tablet / phone / whatever. If you’re running your own Dovecot server then it’s fairly easy to add a read-only folder that’s actually backed by a remote IMAP server.

                                                    I’d love to see some standardisation around this so that I could just click on a link and have my mail client tell my mail server to act as a proxy for a remote read-only IMAP server with that folder appearing in my normal IMAP folder hierarchy.

                                                    1. 3

                                                      I really appreciate public-inbox for this. It is an “archives-first” approach to list management, and archives are available through the web, NNTP, or IMAP. Personally I use NNTP to read lists that have public-inbox archives; it’s pretty easy to add a new group to my newsreader, even if it is hosted elsewhere than my primary NNTP server.

                                                    2. 1

                                                      That is a good point as well. Whenever I advocated for email-based workflows in person, I always mention mailing list archives and how they can be an invaluable tool for people trying to figure out a reason for something long after the author left the company. Somehow, that aspect slipped through the cracks in this post.

                                                      I’m a bit skeptical about calling ticket comment systems maximally persistent. I haven’t had that many jobs in my career, but it seems like every organization is constantly in the process of migrating to a new wiki and a new ticketing system. Because you need to run software to serve the comments in the “old” ticketing system or wiki (i.e., the raw database contents are kind of useless without a viewer), I consider them equally unreliable as far as persistence is concerned. (Not to mention that during the prolonged migration, you have two systems and so people ignore one anyway - and it’s not always the old one!) Serving mailing list archives can be anywhere from complicated (fancy web UI reader) or extremely simple (static mbox people can import as needed).

                                                      I agree that personal email conversations, even though they are email, aren’t great for communicating with your team. But this is no different from using any other 1:1 medium and so a bit out of the (implied?) scope of the post - team-wide communication.

                                                    1. 9

                                                      I sometimes feel like the only person here who hates email for anything other than longer-form communication with one or two other humans. No, I don’t want to comment on pull requests over email, there’s a lovely web interface for that that shows me syntax-highlighted diffs and lets me dig further into a diff easily. No, I don’t want to manage task tickets over email, there’s also a lovely web interface for that and it shows me a visual representation of what’s happening. No, I don’t want to receive an email when something needs my attention, that’s what Slack (or whatever) is for. No, I don’t want to have large discussions over email, I want to see the conversation thread visually and not have to worry about accidentally including a mess of nonsense in my reply (I absolutely would not read Lobsters if it was an email list). And it’s not like I’m a youngster who has never used email, I started using email in the mid-90s. I just don’t understand why everyone loves it so much.

                                                      1. 4

                                                        No, I don’t want to have large discussions over email, I want to see the conversation thread visually and not have to worry about accidentally including a mess of nonsense in my reply (I absolutely would not read Lobsters if it was an email list).

                                                        Don’t forget forget the top vs. bottom posting or plain text “debates”, which everyone in the real world ignores because they use graphical email clients. A lot of email enthusiasts feel detached from the reality of how people actually use tools when they get into it.

                                                        1. 2

                                                          Because it is familiar, reliable, and it doesn’t change out from under me every time some web designer chasing the fad of the week gets a wild hair. Web based mail user agents change that picture a bit, because the user ends up being at the mercy of web designers, but I don’t use those.

                                                        1. 1

                                                          I meant to tag with “email” and “practices”. But a11y works too…

                                                          1. 3

                                                            I’m not a fan of such laws. They make it impossible for e.g. small car repair shop to make website by themselves, for example in Microsoft Word. Even if they buy making of website from professionals: one misplaced ARIA tag and you get huge fine, having websites became dangerous.

                                                            What these car repair shops, cafes and bodegas will do? They will make account in Instagram instead of website. This is much worse for people with disabilities than static website made in Word. Lots of text will be in jpegs.

                                                            1. 1

                                                              I am torn about this sort of thing myself, and I’m a blind person. I mean, all laws come with an implicit threat of punishment for noncompliance. Right action done in order to comply with the law is coersed, not voluntary, and I have a problem with that. But lobsters isn’t a place for that kind of philosophical discussion.

                                                              I do believe that laws should apply differently based on the size of an organization. We’re talking about a large regional chain here, not a local small business.

                                                            1. 3

                                                              The second feature is automatic dates. The thing I noticed about all the other static site generators is they leave the time tracking to the author. For me, I hate keeping track of dates.

                                                              That is one of my own pet peeves. I worked somewhere that used a static site generator, and I recall a few times where someone’s post would fail to appear on the blog because they flubbed the date string. E.G., the date was in the future, had a badly formatted timezone, etc. In at least one instance someone wrote PST for the timezone where they should have written PDT, or vice versa. We’d always waste time scratching our heads and trying to figure out what went wrong, only to realize that it was a bad date. Computers are great at this sort of book-keeping, so let them do it.

                                                              One of these days I will write my rant about how much I hate the Gregorian calendar.

                                                              French Revolutionary Calendar FTW?

                                                              1. 10

                                                                And here’s an example of a physical Winn-Dixie location discriminating against blind customers in 1998:


                                                                Dr. Jernigan announced to the Board that someone at the Winn-Dixie supermarket nearest the convention hotel had called hotel management and warned them not to send over any more blind people. Dr. Jernigan commented that some response was required, and President Maurer appointed a committee composed of Charlie Brown and Peggy Elliott, both of whom are attorneys, to contact the store manager and resolve the situation and educate store staff about the law.

                                                                I wonder what blind people ever did to Winn-Dixie?

                                                                1. 0

                                                                  Flustered the employees and killed throughput to the point that they were losing quite a bit of sales, presumably. Having the occasional customer who needs special accommodation is something any store is prepared to deal with; having a thousand of them drop in next door, and the hotel concierge directing everyone who needs groceries your way (in a pre-“just check your phone” culture), is a crisis that I doubt anyone is ready for.

                                                                  1. 2

                                                                    Hence why the ADA exists, because as a society (well insofar as the federal gov’t representing the will of the people) we want to say “we should provide reasonable accomodations for people with disabilities, even though it’s not in a business’ interests to do so”.

                                                                    I think a lot of people try to make some hand-wavy “untapped market” thing but really it’s about treating people with at least a bit of dignity, cuz markets aren’t going to just solve that. And even in the 98 story it at least ended with some resolution, with the store manager saying they’ll try to accommodate.

                                                                    1. 3

                                                                      Sure. But nobody in this story had any reason to refuse to provide reasonable accommodation, and it hasn’t been made apparent that anyone did. It’s a story, and people like stories better when they have villains in them, but real life rarely operates that way.

                                                                      It’s worth noting that what the law actually requires in that department is whatever “is able to be carried out without much difficulty or expense” considering “the effect on expenses and resources” and “the impact upon the operation of the facility”.

                                                                    2. 1

                                                                      Here is a bit of an unfair comparison, and I do see the problems with it. But let’s suppose as a thought experiment, that instead of a convention of blind people, it was a convention of $ethnicity who is often negatively stereotyped as having a propensity for shoplifting? What would be the response to a store manager saying, “Please don’t send any more $ethnicity people”? Realize this was a large chain supermarket in a huge metro area, Dallas Fort Worth, in Texas in the US. Might they have other options than immediately resorting to discrimination?

                                                                      Assuming it was just a throughput problem also assumes they were acting in some degree of good faith. I’m not sure they were. I was actually at the convention in question – the only such event I’ve ever attended – but I don’t recall the details of the incident. That was many years ago.

                                                                      1. 3

                                                                        There’s not much reason to assume bad faith — what possible motive? As you said in the first place, what did blind people ever do to them? An explanation that involves ordinary (slightly stupid) people acting in ordinary (slightly stupid) ways is almost always the correct one.

                                                                        In fact I’ll go a little bit further in defense of the imaginary ordinary person and suggest that what they meant to ask (and perhaps even what they did ask — remember, we only have a third-hand report, and not an unbiased one) was “could you please not send us all of the blind people?” In other words, a little load-balancing would have been beneficial.

                                                                        I would take offense if they were turning people away at the door, but in my universe (not necessarily the one where the US Code applies) it’s fair enough for people to talk, and cooperate, without threats or violence. To construe the phone call as a wrong worthy of legal notice requires one to view people as basically helpless blobs in the hands of unfathomable “corporate” powers, while at the same time viewing an underpaid supermarket manager as being one of those unfathomable powers. I don’t believe either one.

                                                                        As for your unfair example, yeah, it’s a bit too unfair to work. Not only because the behavior would be stupid (a stereotype is not a good basis for much of anything), but because shoplifting is, in fact, a crime (and a very common one), so dealing with it falls within a well-defined paradigm. Being blind is definitively not a crime, so the response has to be different.

                                                                        So again, let’s go back to this manager, who’s thinking “okay, we weren’t prepared for this, what can I do? I don’t have authority to call more employees in, and anyway, I would have to pay them if I did, and that’s not in the budget. I definitely can’t throw all the blind people out. I guess we can just ride it out, and the regional manager will probably understand and not fire me, but it would be better for me if I could at least say that I tried something. Someone in front-end told me that they’re all coming from this conference at the Hyatt and the front desk is sending them here. Maybe I can call the Hyatt and ask them to send people somewhere else for a little while.” Violà.

                                                                  1. 6

                                                                    There have been trojans found in ./configure scripts (look it up), which is why I regularly advocate for abandoning autotools. And the response I usually get is “Let’s not talk about that, please.” A plaintext blob is still a blob.

                                                                    1. 4

                                                                      Shouldn’t the solution be sandboxing the build? Instead of … what are you proposing instead of autotools that could eliminate the possibilities of trojans in the build process exactly?

                                                                      1. 4

                                                                        I absolutely love BSD Makefile syntax. A project I maintain is a good example of a simple BSD Makefile. For reference, I’ve posted it below.

                                                                        SHLIB=	pushover
                                                                        SHLIB_MAJOR=	0
                                                                        SRCS=	libpushover.c sanity.c
                                                                        INCS=	libpushover.h
                                                                        CFLAGS+=	-I${.CURDIR} -I/usr/local/include
                                                                        LDFLAGS+=	-L/usr/local/lib
                                                                        LDADD=		-lcurl -lsbuf
                                                                        .if defined(PREFIX)
                                                                        LIBDIR=		${PREFIX}/lib
                                                                        INCLUDEDIR=	${PREFIX}/include
                                                                        .include <bsd.lib.mk>
                                                                        1. 1

                                                                          Which is fine if you are happy to depend on bsd.lib.mk existing, but if you’ve ever looked inside that file then you’ll be absolutely horrified if anyone claims it is simple or readable.

                                                                          1. 1

                                                                            I’ve hacked on bsd.lib.mk, wasn’t difficult for me.

                                                                          2. 1

                                                                            I meant to reply to the comment above yours. Sorry!

                                                                            1. 1

                                                                              I usually try to make my makefiles OS-agnostic by trying to adhere to the POSIX makefile spec (w/o the GNU or BSD extensions).
                                                                              But the neatness and brevity of BSD makefiles astounds me.

                                                                              1. 1

                                                                                Yeah. I generally don’t need to worry about supporting non-BSD systems.

                                                                            2. 1

                                                                              Sandboxing could prevent a trojaned shellblob from harming the build host, but it wouldn’t prevent it from tampering with the build product.

                                                                              One point worth making is that a configure.ac or configure.in is amenable to auditing, so projects that use autotools without distributing a prerolled ./configure shellblob don’t have this problem. It’s bad practice to check ./configure into git, so a lot of people don’t do that. Nowadays, a source tarball that is essentially output from git archive is really common. So it’s a point less worth arguing as time goes by.

                                                                              1. 1

                                                                                Sandboxing could prevent a trojaned shellblob from harming the build host, but it wouldn’t prevent it from tampering with the build product.

                                                                                That’s not a particularly interesting threat model. Anyone with the ability to trojan a configure script that you run also has the ability to trojan any of the source files in the build that the configure script is generating.

                                                                                1. 1

                                                                                  You “regularly advocate for abandoning autotools”, and I was trying to ask what you propose for people to use instead that would be safe from trojans.

                                                                                  1. 1

                                                                                    I don’t have a one size fits all solution to advocate. CMake is okay; I’ve had some experience with it. Meson looks like it might be interesting.

                                                                                    In a lot of cases a makefile and a judicious use of pkg-config is good enough.

                                                                                    1. 1

                                                                                      Nothing is truly safe, but the generated configure scripts is usually well over 10,000 lines of hard to read shell script, and few people will look at that, if any. It’s incredibly easy to hide something in there, even for larger projects with quite a few contributors. You can try to hide something in the main code or somewhere else too, but it’s much more likely to be noticed.

                                                                              1. 4

                                                                                At my last job, we wrote a Python script that was intended to be called frequently. All it did was call out to an external API and print a result on stdout. Dumb dead simple code. It took half a second to run. Given the situations in which it was intended to be used, half a second of running time was totally unacceptable.

                                                                                I did some profiling, and most of the wall-clock time was spent at startup, in one statement:

                                                                                import pkg_resources

                                                                                That wasn’t even in our code. It came from one of our dependencies. After doing some research, I discovered that the use of pkg_resources was completely optional. The importing library even had a conditional block so that it would work if pkg_resources was not found.

                                                                                I wrote a custom importer to use with this script. It raised ImportError when something attempted an import of pkg_resources. It shaved well over a third of a second off of the average wall clock time for the program, bringing it back within the bounds of acceptability.

                                                                                1. 15

                                                                                  I think I agree with the first person who wrote him a letter. There is a difference between finding more novel and varied examples and picking examples designed to goad your readers.

                                                                                  Please in the future, remember that we, the book buyers, are looking for information about using PL/SQL. I am as tired of the emp and dept tables as you are, but less distracting examples would have been more appropriate.

                                                                                  Everyone has a political view and sometimes that arises legitimately in technology but I think it’s just basic self-control to express your political view only where it really might help something.

                                                                                  1. 21

                                                                                    The dude’s point is that we all have a political perspective, and we’re expressing it, either explicitly or implicitly. He chose to express his explicitly through the examples in his textbook.

                                                                                    If you write a database text and fill it with department / employee type examples, shopping examples, and so forth, then you are implicitly promoting a capitalist world view, the same world view that does not bat an eye when using degrading terms like “human resources”. At least here in the US, this sort of thing goes unquestioned, because of the dominant ideology.

                                                                                    1. 5

                                                                                      Yes, it’s implicit, it’s unquestioned and nobody bats an eye - and that’s why it makes for better examples.

                                                                                      Examples require the use of social territory. That territory can be either unquestioned good or questioned territory. When choosing examples in questioned territory, you engage in active cultural participation; when choosing examples in unquestioned territory, you engage in passive cultural participation. Examples should engage in passive participation, because that way they are relatable to the greatest number of readers.

                                                                                      (You can also use unquestioned bad territory, such as defining a database schema to count Jews in the Holocaust for the Nazis, but then nobody will buy your book.)

                                                                                      1. 9

                                                                                        I don’t see why “nobody bats an eye” is a desirable quality for examples or why “active cultural participation” is a bad thing.

                                                                                        It’s not at all clear to me that the examples given are not relatable or that “relatable to the greatest number of readers” should even be a core value. Perhaps provocative examples engage readers more and cause them to think about the examples more.

                                                                                        1. 5

                                                                                          Would be curious how you’d feel if it were something sorting countries by iq or something.

                                                                                          Would you be happy to be engaged, or be distracted by a thinking about testing methodology and things like that?

                                                                                          1. 3

                                                                                            I’d have to see it in context to find out how I’d react. IQ is strongly related to class and similarity to the people who devised the test, and such a table might be part of a demonstration of that.

                                                                                            Certainly if an example just seemed pointlessly offensive I would think less of the author and maybe choose a different textbook.

                                                                                            But I think equating a hypothetical very racist example with some examples that are a bit left of centre in the USA is unfair.

                                                                                            1. 3

                                                                                              A substantial amount of political dispute in the English speaking world is precisely about what speech counts as racist and therefore legitimately stigmatizable. Using data that implies that cognitive capacity is meaningfully different between different countries of the world in a programming example constitutes a political assertion that this idea is not stigmatizable; in the same way that the article’s example about a war criminal database constitutes a political assertion about how people should see Henry Kissinger.

                                                                                        2. 6

                                                                                          But now you’ve thought about it, so it has become active participation. From now on you are obliged to make sure your examples completely apolitical.

                                                                                          Consider engineers have a code of ethics, https://en.wikipedia.org/wiki/Order_of_the_Engineer

                                                                                          If your work includes producing examples they should “serve humanity”. I cannot conscientiously make examples that promote capitalism, but giving examples that might make people think about world affairs would be okay.

                                                                                          1. 4

                                                                                            Yes, it’s implicit, it’s unquestioned and nobody bats an eye - and that’s why it makes for better examples.

                                                                                            That assumes a lot from the readership. For a mundane, apolitical example, I submit children to this discussion. For most my childhood due to various reasons, I only had access to a Pentium. It didn’t have a network connection, and I eventually installed Linux on it. Because Linux made it so easy to code, I would try to check out books from the library and learn how to write code, but all the examples were completely unrelatable to me as a pre-teen. Employee this, business that, I realized even at the time that the examples were meant to be highly relatable to practitioners, but I honestly found math much more interesting than these soulless books because I was unable to relate to them in any way. That was one of the big reasons I started out coding by trying to write games; game programming books felt much more relatable to me as a kid who read a lot of books and played video games than these soulless books about employee hierarchies and recipes.

                                                                                            Also, it’s important to keep in mind that the conditions that make something unpolitical are pretty restricted in context. Someone growing up in a developing country or a country with a very different economic ideology will probably find these staid business examples just as unrelatable as children. International editions of textbooks frequently do change examples for exactly this reason.

                                                                                            1. 1

                                                                                              I would try to check out books from the library and learn how to write code, but all the examples were completely unrelatable to me as a pre-teen. Employee this, business that, I realized even at the time that the examples were meant to be highly relatable to practitioners, but I honestly found math much more interesting than these soulless books because I was unable to relate to them in any way.

                                                                                              I also started learning at a young age, and I find this attitude so alien.

                                                                                        3. 5

                                                                                          Everyone has a political view and sometimes that arises legitimately in technology but I think it’s just basic self-control to express your political view only where it really might help something.

                                                                                          I am totally with you on this, and do my best to keep my political perspectives away from the technology work I do as much as I can. I have worked on projects with ethical/political considerations (whether someone might consider a few of these projects ethical depends on their personal political leanings.) Definitely a touchy subject.

                                                                                          That being said, I have a really hard time empathizing with the readers who wrote in to complain that the examples are too distracting. I believe a database book aught to have concrete examples while teaching the abstract concepts (e.g. it’s a book about writing databases in general, not “how to keep track of war criminals”). My own personal reaction to the examples talked about are “ok, whether I agree with the premise or not, these examples have interesting abstract concepts that they’re illustrating.” There are lots of systems that exist in this world whose existence I fundamentally disagree with, but where I’d also love to pop the hood and figure out how they work!

                                                                                          In fact, as I sat here thinking about this, I started wondering if, for me, this style of examples might actually help cement specific concepts with easy mental look-up keys; I can imagine coming to a database design problem and thinking “oh, this is like the Kissinger problem.”