Category: Software Engineering

If you haven’t had the chance, you really should pick up a copy of Common Lisp: A gentle introduction to symbolic computation by David Touretzky, in there you will find a series of “templates” for recursion. Consider these like tools in you toolbox.

The following is a presentation of these “recursion templates” in Scheme code with generous examples. Not as clumsy or imprecise as a for loop, they are elegant weapons, from a more civilized era.

Double-Test Tail Recursion

This template is a simple search recursion across a list.

(define (has-odd? lst)
	(cond
		((null? lst) #f)
		((odd? (car lst)) #t)
		(else
			(has-odd? (cdr lst)))))

As you see, we have a Double-Test at the beginning of the cond, the first tests null, and the second tests for the needle that we are searching for in the haystack that we’ve been passed.

In Touretzsky’s version, the first clause returned nil, I’ve elected to return #f which I think is more correct, as an empty list obviously does not have any odds in it. I prefer a uniformity in return types, even though in this example ‘() is certainly not true, therefore it is functionally equivalent.

Search a list for a value

(define (in-list? needle haystack)
    (cond
      ((null? haystack) #f)
      ((equal? (car haystack) needle)
        #t)
      (else
          (in-list? needle (cdr haystack)))))
(in-list? "Hello" '("Hello" "World")) ; #t
(in-list? "Hello" '("Goobye" "World")) ; #f

Single Test Augmenting Recursion, or Incrementing Recursion

This is a way to recursively accumulate or increment some value, such as counting.

(define (count-items lst)
    (cond
        ((null? lst) 0)
        (else
            (+ 1 (count-items (cdr lst))))))

List Consing Recursion

Here we build a list of values as we go along, notice that we are decrementing, so the numbers are in reverse order.

(define (count-down n)
	(cond
	  ((zero? n)
	   '())
	  (else
		(cons n (count-down (- n 1))))))

An alternative to this would be:

(define (count-up n)
  (let loop ((i 1))
    (cond
      ((> i n) '())
      (else
        (cons i (loop (+ i 1)))))))

Simultaneous Multivariate Recursion

Here we define a function that accepts an ordinal, like 1st, 2nd, 3rd (without the ordinal suffix), and
return that element.

In Touretzky’s book, he reimplements nth, which starts at zero, our function however does not accept 0.

(define (snatch i lst)
  (cond
    ((<= i 1)
      (car lst))
    (else
      (snatch (- i 1) (cdr lst)))))

Conditional Consing

Here we have two paths, one (number?) which conses the car of lst with the result of a recursive call to nums, or, which simply returns whatever would be returned via the continuation. Notice how the numbers come out in order!

(define (nums lst)
  (cond
	((null? lst) '())
	((number? (car lst))
	 (cons 
	   (car lst)
	   (nums (cdr lst))))
	(else
	  (nums (cdr lst)))))

Multiple Recursion

Here we combine the results from two independent recursions, each call has the possibility of generating 2 more recursions and on and on.

(define (fib n)
  (cond
	((equal? n 0) 1)
	((equal? n 1) 1)
	(else
	  (+ (fib (- n 1))
		 (fib (- n 2))))))

Car/Cdr Recursion

(define (find-number lst)
  (cond
	((number? lst) lst)
	((atom? lst) #f)
	(else
	  (or (find-number (car lst))
		  (find-number (cdr lst))))))

Page is a work in progress

Big things die slow. The internet has been dying now for about 10-15 years. In reality, it started dying on April 13, 2000. The day Metallica sued Napster. This isn’t a defense of file sharing on the internet, it’s just a statement of fact. That was the day shit started getting real online, when the digital and virtual world of the internet had real repercussions from the real world.

Hacking had kind of always been illegal, but that was a reaction in the real world to people crossing the boundary from the internet, or from cyberspace, to affect the real world, so it’s understandable.

But the internet is dying for other reasons.

Passwords are shitty security

Passwords were always a bad idea. But they were convenient, they made it easier to key access to systems and identify users. But they suck. They can be hacked, rather easily. There’s no real solution online. Most websites, like Amazon, or Digital Ocean elect to use two-factor authentication. That’s where you sign in, then twiddle your thumbs while you wait for an email or an SMS with a code, then you enter the code and you’re in.

What happens when you lose the password to your email account? Phone. Or lose your phone entirely?

You’re fucked.

The Public Forum that never was

The internet, as conceived by the angel headed hipsters writing the underlying tech, was a kind of digital Areopagitica. A public forum where the free exchange of information and ideas could exist. And if you’re really, really tech savvy, and you’re ideas aren’t “beyond the pale” it might could be that for you. But imagine if the Areopagitica was Mount Everest. It’s just too difficult to reach in order to be useful, in order to be public.

It doesn’t matter that you can say anything you want, so long as you are at the top of mount everest, because you can’t fucking get to the top of mount everest so it might as well not exist for 99.99% of the population.

The internet is like this. Most people couldn’t even use the internet if it weren’t for browsers, hosting companies, and ISPs. But those companies are private, that makes the internet private. Not in the sense of security, or anonymity, but in the sense of property. It means, in the end, what the “owners” of the pieces of the internet says goes. It means you don’t own anything you produce on or through the network.

If you write a book on Google Docs, it’s not really your book. It is in a copyright sense, but not in a real ownership sense. If Google decides it doesn’t like you, or your book’s content, it can simply close your account. Is has no obligation to return your files. Or your emails. Who owns them? If you use Gmail, google does. Google can save them, read them, or delete them as it pleases.

Our naive understanding of the internet is that it is a public forum, but it is not. It is private property, anything you say, do or make there, is constantly at risk. It’s a small risk, and so long as you toe the line in society, it is a risk you’ll probably never run afoul of.

The creator of Freenet understood this. Unfortunately, the only people he could get to use his network were the rejects of the wider internet, drug dealers, wannabe contract killers, and kiddie porn producers. Tor is much the same, except everyone on Tor is an epic moron. Question: How do you hide from the government? Answer: Use an abandonware network created by the Office of Naval Intelligence? Take that NSA.

Encryption is effectively illegal

Crypto nerds always do my head in. They’re so stupid it hurts sometimes. Every major country in the world has incredibly broad laws about encryption. If the police show up at your door, you are legally obliged to turn over all passwords and encryption keys if asked. Refusal to do so is an automatic jail sentence. You can effectively be imprisoned for life, because you won’t be released until the police are satisfied you’ve given them everything. Even in the USA. Especially there.

The thing no one seems to want to admit is that the point of encryption has always been hiding shit from the government, not hackers. The truth is, everyone is a little bit criminal. Everyone cheats, lies, and occasionally steals: something. Ever downloaded a pdf of an ebook from a shady Russian website? Ever watched a movie online on one of those websites in Barbados? Yeah, fuckin’ thieves, the lot of you.

Piracy: No hardware was raped, no databases pillaged

The basic problem is there is a fundamental difference between the pays réel and the pays légal. In the real world, everyone knows that “piracy” (god, that word used to mean something) is a victimless crime. At least, that’s how most internet denizens act. But legally, it’s not. So don’t do it. But you still do, everyone does. And the truth is, software/music/video piracy is NOT a victimless crime. At least not when everyone is doing it. The price of books has collapsed, along with the quality, in part due to vanity publishing, but in another part due to the ubiquity of Chinese and Russian ebook download sites.

The quality of movies, and the costs associated with consuming them, have been thrown into chaos. That’s partly due to a dying industry, and technological disruption. The rise of youtube and The Left(TM) have had significant negative impacts on visual media as well. But part of this chaos and degradation is the ubiquity of digital illegal distribution. The thing is, movies should be making a lot more money than they make. It might seem like they’re doing good, breaking box office records, but today it’s a global market. A decent movie could make a billion opening week, easily.

We’re all the collective victims of a victimless crime (and admittedly many other factors). But we’re also the perpetrators.

Full Stack Development

6 years ago when I was working on Salor, we came up with the brilliant idea of offloading much of the work from the server to a thin-client/browser. At that time, only sites like Facebook were really doing this, pushing out as much Javascript as possible and having the client build the page. It was a new idea, and it was a great idea: until it wasn’t. Now everyone is doing it, there are plenty of frameworks (angular.js, Vue.js etc). Now my chrome spikes to 100% CPU frequently on my Acer V Nitro gaming laptop. I can, in some cases, get worse perfomance from my browser than a AAA video game.

That’s because I have tons of tabs open, taking up gigabytes of memory. (The idea, the very fucking idea, of websites taking up GIGABYTES of memory is…so…fucked). We’re getting less and less efficient, and more and more bogged down by kitchen sink frameworks, and shit code they encourage.

This is all made worse by the domination of OOP and MVC within server side frameworks.

Mobile First, Retardation Second

Added onto the shitshow that is full stack development is the unadulterated bullshit of mobile devices. As if the already crudded up and mostly useless solipsistic internet needed to also be deliverable by a pocket sized mirror into the mediocrity of your own soul. I can’t think of anything stupider than reading your twitter feed on the most advanced piece of computer hardware ever designed for mass consumption.

I hate the internet, and I hope it dies

It really already has. What we have today is not the internet of my youth. Today there is no internet. There’s just Google, and Amazon, and Wikipedia. It’s all just ideologically sanctioned LCARS. It’s useful, and I use it. But we should stop calling it the internet, and start calling it the Cortex, or something like that.

There’s no such thing as web development, or web programming, it’s all fullstack this, and cloud that. We all just sit around and spool up kubernetes to serve microservices that sell people shit, or force feed them newspeak and goodfacts.

I feel like Tom Wilson.

In another post, I discussed how to build Chez Scheme from source for Debian 9 Stretch, here is how to setup SLIB.

git clone https://github.com/taktoa/slib.git
cp -fr slib /usr/share
cd /usr/local/lib
ln -sf /usr/share/slib .
chmod 777 /usr/share/slib
touch /usr/bin/chez
chmod 777 /usr/bin/chez
vim /usr/bin/chez

Edit the file /usr/bin/chez to be:

#! /usr/bin/scheme
(load "/usr/share/slib/chez.init")

There are a few gotchas when building Chez Scheme from source. The first is that you’ll need to install libncurses5-dev and libx11-dev

$ apt install build-essential libncurses5-dev libx11-dev

The next thing to consider is that you cannot build on a server or Virtual Machine with less than 4 Gigabytes of memory. This is because the nanopass compiler is a memory hog (see this issue) and there seems to be no fix.

Welcome to Scheme/LISP – Where there is always some bullshit hurdle to getting shit done.

Here are the steps you can take to deploy Chez Scheme on a remote server, such as a VPS that doesn’t have enough memory.

  1. Download and install: https://www.virtualbox.org/wiki/Downloads
  2. Download an iso of your version of linux, make sure to match perfectly with what is running on the server. For me it’s Debian 9 x64.
  3. Install a minimal linux system, then run: apt install build-essential libncurses5-dev libx11-dev rsync
  4. Clone the ChezScheme repo, then in that dir run ./configure && make
  5. rsync, or scp, ChezScheme to your server with: rsync -av ChezScheme/ user@server.com:/path/ChezScheme
  6. Once the sync is don, ssh to your server, into your ChezScheme dir, and run: make install

That should be about it!