macOS Desktops limit?

If you’ve ever wondered how many Desktops you can have on macOS, the answer, based on my 10 second test is 16. I do, however, have two apps in fullscreen mode (OmniFocus and Music.app).

Foo

I wonder if this is per screen. If any of you has an external monitor, please test and let me know!

Fun fact: you cant do “⌘⇪3” (Command+Shift+3) to capture the screen if you’re in Mission Control, instead I ran the following inside a terminal.

sleep 5 && screencapture /tmp/foo.png

If you like to nerd out on Unix-y stuff, here’s a screenshot from the manual page of screencapture(1).

Screenshot 2023 11 02 at 7 52 29 PM

Better documentation is needed, indeed.

That’s all folks…

Reply via email.

Upcoming migration

In the coming days/weeks, this blog will be migrated to a new address. Notably, the subdomain will be dropped and I will use antranigv.am for my blog.

I’ve been meaning to do these changes for a while now, and it occurred to me there’s no time like the present. Of course, the biggest kicker was discussing about this with my good friend Rubenerd.

Three major changes:

  • weblog.antranigv.amantranigv.am
  • The blog’s name will be changed from “Freedom Be With All” to something… else
  • The theme, while staying the same, will be modified a bit. Mostly the internals

I always had a love and hate relationship with the subdomain weblog., however, I realized that the only thing on my homepage is little information such as projects I’m working on, some contact info and some banners.

While it’s a cool static page with a cool theme, I generate it in a complex way: OPML → XSLT → HTML, to be specific.

By moving the blog to the homepage, it will make it a better “reading experience” (is RX a thing? or is that part of UX as well?)

The name of this blog “Freedom Be With All” has a bit of history.

Initially, I only had an Armenian blog (which used to be blog.antranigv.am moved to antranigv.am/blog and currently settled to անդրանիկ.հայ which is “my name in Armenian dot Armenia’s IDN TLD”), I was too scared to blog in English.

The title of my Armenian blog was and still is “Ազատութիւն Ամենեցուն”, literally meaning “Freedom to all”. It’s a “mod” of the common “Peace to all” phrase mentioned in The Divine Liturgy Of The Armenian Church.

Personally, freedom is the highest value of all, hence I went with it, instead of peace.

The tagline will stay the same: I’m your worst nightmare. You see, when I was a kid, back in school, back in Syria, I was bullied (I mean, who wasn’t?), but not for my nerdiness, instead, for my “sharpness”. It wasn’t cool to know things, read books, talk with strangers on this thing called “the internet”. It wasn’t cool to talk about Star Wars all day (don’t you have history to study? who cares about WHY the Trade Federation attacked Naboo). It wasn’t cool to “know how to run pirated PlayStation games” because we were, well, poor is the right word here.

But I loved the internet, and the people on the internet introduced me to Unix, specifically to Linux. And that got me to (pirate, of course, because Syria, and) watch a documentary named Revolution OS, where the intro starts with Eric S. Raymond telling a story, ending with “I’m your worst nightmare”.

That feeling, of being such a good computer hacker, that you feel like a god in front of the computer and you feel that you can be a whole corporation’s nightmare is what made me feel powerful, is what made me feel “un-bully-able”. After that I would spend my days (well, technically nights, after my father went to sleep) chatting on IRC, reading books about programming, cracking the neighbour’s WiFi, reinstalling X11 3 times, and being nicer when you know you have the ability to be batman a nightmare.

All of this story aside, I don’t know what to name the blog. Maybe “Antranig Vartanian”, maybe “Antranig’s Notes”, maybe “antranigv”. Still not sure… Have a thought? Reply in the comments 🙂

The theme of the website will stay as is, but some nice modifications will be added, like a calendar, maybe a tag cloud, etc.

Finally, and I just remembered about this while I was typing this post: ActivityPub!

Dear lazyweb

I have a WordPress blog that uses the ActivityPub plugin, which means that you can follow it from the fediverse, e.g. from Mastodon!
However, I am planning to migrate the domain of the blog. Do I need to keep a static JSON somewhere meaning the “account” has migrated?

Any tips will be appreciated!

Otherwise, around 40 nice people will need to follow again 🙁

Wow, this post went more than I expected!

Thank you for reading (or skimming!)

That’s all folks… 

Reply via email.

Antranig Vartanian

October 31, 2023

Once a month, the WordPress app on my iPhone stops working. Specifically, it stops loading and sending data. It just “hangs” there. I’m honestly considering using the mobile web interface to blog remotely.

I wish there was MarsEdit for mobile…

Any alternatives or suggestions? Maybe I should use the “Post via Email” feature like back in the good old days 🙂

Reply via email.

Antranig Vartanian

October 26, 2023

The following happened in a group chat (technically, XMPP Multi-User Chat)

<inky> @antranigv, looks like the sarian website is broken again

<antranigv> @inky, fixed! It was an SSL/TLS certificate issue

<inky> @antranigv, It seems that now, the bot that cross-posts the submissions from sarian to here is not working

<antranigv> Looks like there’s an issue with Ruby. I have to upgrade it

<tigran> This is how the robot revolution begins!

<inky> If we are going to "do it", it will end just like it starts: one robot will fail because of SSL, the other because of a wrong version of ruby.

I’ve been ROFLing for 3 minutes now… xD

Cheers.

Reply via email.

bhyve CPU Allocation Test for 256 core machine

During the last bhyve weekly call, Michael Dexter asked me to run the bhyve CPU Allocation Test that he wrote in order to see if number of CPUs in the guest makes the system boot longer.

Here’s a post with the details of the test and my findings.

The host machines runs the following

# uname -a
FreeBSD genomic.abi.am 13.2-RELEASE FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC amd64

# sysctl hw.model hw.ncpu
hw.model: AMD EPYC 7702 64-Core Processor
hw.ncpu: 256

# dmidecode -t processor | grep 'Socket Designation'
        Socket Designation: CPU1
        Socket Designation: CPU2

# sysctl hw.physmem hw.realmem hw.usermem
hw.physmem: 2185602236416
hw.realmem: 2200361238528
hw.usermem: 2091107983360

Basically, it’s FreeBSD 13.2, with 2TB of RAM, 2 CPUs with 64 cores each, 2 threads each, totaling 256 vCores

The test runs a bhyve VM with minimal FreeBSD, that’s built with OccamBSD. The main changes are the following:

  • /boot/loader.conf has the line autoboot_delay="0"
  • There are no service enabled
  • /etc/rc.local has the line shutdown -p now

The machine boots and then it shuts down.

Here’s what I’ve got in the log file →

Host CPUs: 256
1 booted in 9 seconds
2 booted in 9 seconds
3 booted in 9 seconds
4 booted in 9 seconds
5 booted in 9 seconds
6 booted in 9 seconds
7 booted in 9 seconds
8 booted in 9 seconds
9 booted in 10 seconds
10 booted in 10 seconds
11 booted in 10 seconds
12 booted in 11 seconds
13 booted in 10 seconds
14 booted in 11 seconds
15 booted in 12 seconds
16 booted in 9 seconds
17 booted in 12 seconds
18 booted in 18 seconds
19 booted in 14 seconds
20 booted in 15 seconds
21 booted in 22 seconds
22 booted in 17 seconds
23 booted in 23 seconds
24 booted in 10 seconds
25 booted in 10 seconds
26 booted in 17 seconds
27 booted in 14 seconds
28 booted in 15 seconds
29 booted in 12 seconds
30 booted in 15 seconds
31 booted in 31 seconds
32 booted in 19 seconds
33 booted in 15 seconds
34 booted in 32 seconds
35 booted in 18 seconds
36 booted in 22 seconds
37 booted in 24 seconds
38 booted in 17 seconds
39 booted in 24 seconds
40 booted in 13 seconds
41 booted in 15 seconds
42 booted in 23 seconds
43 booted in 37 seconds
44 booted in 21 seconds
45 booted in 19 seconds
46 booted in 12 seconds
47 booted in 17 seconds
48 booted in 19 seconds
49 booted in 17 seconds
50 booted in 18 seconds
51 booted in 15 seconds
52 booted in 20 seconds
53 booted in 14 seconds
54 booted in 22 seconds
55 booted in 18 seconds
56 booted in 17 seconds
57 booted in 92 seconds
58 booted in 15 seconds
59 booted in 15 seconds
60 booted in 17 seconds
61 booted in 16 seconds
62 booted in 22 seconds
63 booted in 17 seconds
64 booted in 12 seconds
65 booted in 17 seconds

At the 66th core, bhyve crashes, with the following line

Booting the VM with 66 vCPUs
Assertion failed: (curaddr - startaddr < SMBIOS_MAX_LENGTH), function smbios_build, file /usr/src/usr.sbin/bhyve/smbiostbl.c, line 936.
Abort trap (core dumped)    

At this point, bhyve crashes with every ncpu+1, so I had to stop the loop from running.

I had to look into the topology of the CPUs, which FreeBSD can report using

sysctl -n kern.sched.topology_spec

<groups>
 <group level="1" cache-level="0">
  <cpu count="256" mask="ffffffffffffffff,ffffffffffffffff,ffffffffffffffff,ffffffffffffffff">0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255</cpu>
  <children>
   <group level="2" cache-level="0">

[...]

   </group>
  </children>
 </group>
</groups>

You can find the whole output here: kern.sched.topology_spec.xml.txt

The system that we need for production requires 240 vCores. This topology gave me the idea to run that manually, using the socket, cores and threads options →

bhyve -c 240,sockets=2,cores=60,threads=2 -m 1024 -H -A \
    -l com1,stdio \
    -l bootrom,BHYVE_UEFI.fd \
    -s 0,hostbridge \
    -s 2,virtio-blk,vm.raw \
    -s 31,lpc \
    vm0

And it booted all fine! 🙂

240 booted in 33 seconds

For production, however, I use vm-bhyve, so I’ve added the following to my configuration →

cpu="240"
cpu_sockets="2"
cpu_cores="60"
cpu_threads="2"
memory="1856G"

And yes, for those who are wondering, bhyve can virtualize 1.8T of vDRAM all fine 🙂

For my debugging nerds, I’ve also uploaded the bhyve.core file to my server, you may get it at bhyve-cpu-allocation–256.tgz

As long as this is helpful for someone out there, I’ll be happy. Sometimes I forget that not everyone runs massive clusters like we do.

That’s all folks…

Reply via email.

Antranig Vartanian

September 12, 2023

After 6 weeks of being unproductive, I’m finally able to get things done thanks to a whole day of planning, awesome software and friends pushing me to do better.

See you soon!

Reply via email.

FreeBSD Jail booting & running Devuan GNU+Linux with OpenRC

Two years ago I wrote a blog post named VoidLinux in FreeBSD Jail; with init, where we installed and “booted” VoidLinux in a FreeBSD Jail. I think it’s time to revise that post.

This time we will be using Devuan GNU+Linux, boot things using OpenRC and put some native FreeBSD binaries inside the Linux Jail.

Here’s what I’m running at the moment

root@srv0:~ # uname -v
FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC

To bootstrap the Devuan system, we need debootstrap. Specifically, debootstrap that ships with Devuan Chimaera. We can start by installing debootstrap from ports/packages, and then we can modify the rest.

pkg install -y debootstrap

Now we need to fetch Devuan’s debootstrap, extract it, put some files into our debootstrap and set some symbolic links.

# Path might change over time, check https://pkginfo.devuan.org/ for the exact link
fetch http://deb.devuan.org/merged/pool/DEVUAN/main/d/debootstrap/debootstrap_1.0.123+devuan3_all.deb

# .deb files are messy, make a directory
mkdir debootstrap_devuan
mv debootstrap_1.0.123+devuan3_all.deb debootstrap_devuan/
cd debootstrap_devuan/
tar xf debootstrap_1.0.123+devuan3_all.deb
tar xf data.tar.gz

# We need chimaera (latest, symlink) and ceres (origin)
cp usr/share/debootstrap/scripts/ceres usr/share/debootstrap/scripts/chimaera /usr/local/share/debootstrap/scripts/

Now we can bootstrap our system. I will be using a ZFS filesystem, but this can be done without ZFS as well.

Keep in mind that my Jail’s path is going to be /usr/local/jails/devuan0, modify this path as needed 🙂

zfs create zroot/jails/devuan0

debootstrap --no-check-gpg --arch=amd64 chimaera /usr/local/jails/devuan0/ http://pkgmaster.devuan.org/merged/

The installation should start now but at some point there, we’ll get the following error:

I: Configuring libpam-runtime...
I: Configuring login...
I: Configuring util-linux...
I: Configuring mount...
I: Configuring sysvinit-core...
W: Failure while configuring required packages.
W: See /usr/local/jails/devuan0/debootstrap/debootstrap.log for details (possibly the package package is at fault)

DON’T PANIC! This is fine 🙂 We just need to chroot inside, fix this manually and install OpenRC


chroot /usr/local/jails/devuan0 /bin/bash
# Fix base packages
dpkg --force-depends -i /var/cache/apt/archives/*.deb
# Set Cache-Start
echo "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00chroot
# Install OpenRC
apt update
apt install openrc

We have almost everything ready. We just need to create a password database file that the jail(8) command uses internally.

cd /usr/local/jails/devuan0/etc/
echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > master.passwd
pwd_mkdb -d ./ -p master.passwd
# Restore the Linux passwd file
cp passwd- passwd

We can also move our statically linked FreeBSD binaries into the Linux Jail so we can use them when needed

cp -a /rescue /usr/local/jails/devuan0/native

Now we just need our Jail configuration file. We can put that at /etc/jail.conf.d/devuan0.conf

(This assumes that you’re network is configured similar to “VNET Jail HowTo Part 2: Networking”

# vim: set syntax=sh:
exec.clean;
allow.raw_sockets;
mount.devfs;

devuan0 {
  # ID == epair index :)
  $id             = "0";
  $bridge         = "bridge0";
  # Set a domain :)
  $domain         = "bsd.am";
  vnet;
  vnet.interface = "epair${id}b";

  mount.fstab     = "/etc/jail.conf.d/${name}.fstab";

  exec.prestart   = "ifconfig epair${id} create up";
  exec.prestart  += "ifconfig epair${id}a up descr vnet-${name}";
  exec.prestart  += "ifconfig ${bridge} addm epair${id}a up";

  exec.start      = "/sbin/openrc default";

  exec.stop       = "/sbin/openrc shutdown";

  exec.poststop   = "ifconfig ${bridge} deletem epair${id}a";
  exec.poststop  += "ifconfig epair${id}a destroy";

  host.hostname   = "${name}.${domain}";
  path            = "/usr/local/jails/devuan0";

  # Maybe mkdir this path :)
  exec.consolelog = "/var/log/jail/${name}.log";

  persist;
  allow.socket_af;
}

As you have guessed, we also need an fstab file, that should go into /etc/jail.conf.d/devuan0.fstab

devfs       /usr/local/jails/devuan0/dev      devfs     rw                   0 0
tmpfs       /usr/local/jails/devuan0/dev/shm  tmpfs     rw,size=1g,mode=1777 0 0
fdescfs     /usr/local/jails/devuan0/dev/fd   fdescfs   rw,linrdlnk          0 0
linprocfs   /usr/local/jails/devuan0/proc     linprocfs rw                   0 0
linsysfs    /usr/local/jails/devuan0/sys      linsysfs  rw                   0 0
tmpfs       /usr/local/jails/devuan0/tmp      tmpfs     rw,mode=1777         0 0

Finally, let’s load some kernel modules (in case they haven’t yet)

service linux enable
service linux start
kldload netlink

Let’s start our Jail!

jail -c -f /etc/jail.conf.d/devuan0.conf

Is it running?

 # jls -N
 JID             IP Address      Hostname                      Path
 devuan0                         devuan0.bsd.am                /usr/local/jails/devuan0

Yes it is!

Now we can jexec into it and run things!

root@srv0:~ # jexec -l devuan0 /bin/bash
root@devuan0:~# uname -a
Linux devuan0.bsd.am 4.4.0 FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC x86_64 GNU/Linux

The process tree looks neat as well!

root@devuan0:~# ps f
  PID TTY      STAT   TIME COMMAND
74682 pts/1    S      0:00 /bin/bash
78212 pts/1    R+     0:00  \_ ps f
48412 ?        Ss     0:00 /usr/sbin/cron
41190 ?        Ss     0:00 /usr/sbin/rsyslogd

Let’s do some networking things! Let’s setup networking and install OpenSSH.
(This assumes that you’re network is configured similar to “VNET Jail HowTo Part 2: Networking”)

# Setup network interfaces
/native/ifconfig lo0 inet 127.0.0.1/8 up
/native/ifconfig epair0b inet 10.0.0.10/24 up
/native/route add default 10.0.0.1

# Install and start OpenSSH server
apt-get --no-install-recommends install openssh-server
rc-service ssh start

You should be able to ping things now

~# ping -n -c 1 bsd.am
ping: WARNING: setsockopt(ICMP_FILTER): Protocol not available
PING  (37.252.73.34) 56(84) bytes of data.
64 bytes from 37.252.73.34: icmp_seq=1 ttl=55 time=2.60 ms

---  ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.603/2.603/2.603/0.000 ms

To make the networking configuration persistent, we can use the rc.local file that OpenRC executes at boot.

chmod +x /etc/rc.local
echo '/native/ifconfig lo0 inet 127.0.0.1/8 up' >> /etc/rc.local
echo '/native/ifconfig epair0b inet 10.0.0.10/24 up' >> /etc/rc.local
echo '/native/route add default 10.0.0.1' >> /etc/rc.local

Do you know what this means? It means that now you can have proper ZFS, DTrace and pf firewalling with Linux. Congrats, now you have clean waters.

That’s all folks…

P.S. I would like to thank my mentor, norayr, for showing me how to start/stop OpenRC manually, and the awesome folks at #devuan for their help.

Reply via email.

Antranig Vartanian

July 10, 2023

In case you didn’t know, OpenSMTPd is so outdated on Ubuntu systems, that you’ll need to install it from sources, otherwise expect some TLS issues 🙂

You will need to use the following:

./configure \
 --with-user-smtpd=opensmtpd \
 --with-user-queue=opensmtpq \
 --with-group-queue=opensmtpq

mkdir -p /var/empty

ln -s /etc/ssl/certs/ca-certificates.crt /usr/lib/ssl/cert.pem

Congrats, now you have a proper working SMTP server.

Cheers.

Reply via email.

Link

Alecu Ștefan-Iulian: “Long rant about “obsolete” languages (not):

Long rant about “obsolete” languages (not); contains swearing

Number two: #pascal (and #delphi). Going raw on this one.

“Pascal is just for teaching”. As if a language that’s easy to learn for beginners is bad. #python and #js are used a lot in teaching too and I don’t see them get shit for this. I pity people who start with #c because that’s an unreadable mess. Additionally, it came I think 2 years earlier than C, so it had to deal with the same constraints that C had. It has a lot of low level capabilities and plenty of compiler directives to choose from in case you’re a control freak. We even have asm blocks which, unlike C, aren’t (excuse my Spanish) dogshit to use, we can just reference variables inside them and it works as expected (you have to do some weird stuff in C to get that). We have pointers too and use them decently frequently. Pascal, along with ALGOL-60, was designed as a language for formal specification and teaching of algorithms, but contrary to ALGOL-68, emphasis was put on simplicity (imagine a world in which ALGOL-W was ALGOL-68…).

“Pascal is slow”. What? Pascal was fast even back when Turbo Pascal was all the rage, a direct competitor to C. #apple sure had their reasons to choose Object Pascal (basis for Delphi) when they did the Apple ][ and Apple ///). There also existed UCSD Pascal which ran on the UCSD p-System, popular at that time (it ran actual Pascal p-code, which means it was the Pascal equivalent of the #lisp Machine, really powerful). Free Pascal is on par sometimes with even GCC.

“Pascal is outdated”. News flash for people who’ve only tried Turbo Pascal: we have interfaces, generics, lambdas, Unicode support, database support through a common interface, dynamic arrays, abstract and sealed classes, for..in, operator overloading, static methods/properties, RTTI, type inference and so, so, so much more. We’re more than able to meet modern demands with the amount of libraries at our disposal. It runs on more platforms than it ever has before (I beg you to find me a more portable language than Pascal (and Free Pascal specifically) that’s not C, it’s gonna be a rough realization). I have actual enums that work like symbols, I can have negative indices, character indices, enum indices, whatever. That allows me a lot of freedom (for example, it’s a pain to iterate over enums in C, something I have to deal with in #cpp in my compiler). It’s fast, performant, easy to understand and still has room for improvement.

“Pascal’s syntax is too verbose”. It is verbose in a readable way, unlike some other public, static and void of any elegance main languages that are both terse and verbose in the most cursed way. The syntax is well structured and strict, which is good for not just beginners, but also parsers. In C, a function is 1. its signature and 2. the declaration of variables.. and definition of function which may be mixed up. In Pascal, it’s clear: 1. function/procedure signature, 2. declaration of variables, 3. definition of function/procedure/program. Simple as that, it follows a predictable structure. Don’t even get me started on C’s = vs == (which can BOTH be used as valid Boolean expressions), unlike Pascal where we have := for assignment and = for comparison (they’re mutually exclusive, as in assignment isn’t Boolean and comparison isn’t an assignment). We also have `<>` which is really different from != in C. I don’t need to insert break everywhere in my Case … Of section in Pascal because the syntax is strict and so it knows where to stop. There’s a strict difference between a pointer and a string (we have native strings too, btw, unlike C). We also have native set operators (and sets, obviously); we can check if an element is in a set via in, we can include/exclude elements, compare sets ((symmetric) difference), combine and intersect them). This is all in the language, no extra units needed.

You Pascal and Delphi haters (usually ones that never even attempted to try these languages, as always, the grapes sure are sour) aren’t grateful enough for these languages existing. For one, it’s the first widely used implementation of a bytecode (if you want to put it that way, it’s also the first VM). The chief designer of Delphi went on to create C# (which you don’t seem to have a problem with, mostly, although the Delphi influence is clear as the night sky in the mountains). Also, have you heard of these irrelevant programs named Skype and InnoSetup? Yeah, those ones. News flash: they’re in Pascal (I think Delphi specifically). Delphi essentially pioneered the concept of RAD (rapid application development) in an IDE form which is why it evolved to fit so nicely with GUI development in mind, unlike its C++ sibling in RAD Studio. It’s still hard to beat Delphi in the GUI department (too bad Embarcadero realized a bit too late that they needed a Community Edition… or Linux support). Visual Basic, Visual FoxPro, VB.NET, C#… it all started with Delphi.

I absolutely agree with Alecu about all of this, and about the rest of his rant as well.

There are so many awesome programming languages out there that do exactly what they are supposed to do, and yet no one talks about them, either because they don’t have a C-style syntax, or follow a different paradigm or they are not hyped.

Never underestimate a tiny programming language that gets shit done, or an old programming language that learned from its mistakes.

Reply via email.