@danderson@hachyderm.io
@danderson@hachyderm.io avatar

danderson

@danderson@hachyderm.io

Software developer by day, other kinds of nerd the rest of the time. ADHD says current hobbies are 3D printers, building CNC machines, old computers in space, and general shitposting on whatever grabs my interest.

Nazis, TERFs, other terrible people: please go away, there's nothing for you here.

This profile is from a federated server and may be incomplete. Browse more on the original instance.

danderson, to random
@danderson@hachyderm.io avatar

Really "loving" this learned response I have of finding something that sounds neat, but it's on a podcast so I have to go research the host because there's a significant chance the reason they're podcasting is they're a fascist or sex pest and a self-published podcast is the remaining avenue for "speaking truth to power" or whatever.

Brought to you by: yup, sex pest this time.

danderson, to random
@danderson@hachyderm.io avatar

Having a normal one at the adhd factory again today.

Screen 1: CAD with a partial SNES controller connector, and a dozen reference images for said connector.

Screen 2: MSDS for Americium 241, and related tabs on the limitations of detector technology and calculating exposure (no, I don't have any, and don't intend to acquire any, have not been exposed. Knowing things is just fun).

Screen 3: Common Lisp HyperSpec, open at the definition of RETURN-FROM.

Screen 4: It you, you're in it.

danderson, to random
@danderson@hachyderm.io avatar

Saw Guix described as the closest to a modern Lisp machine there is. It's a niche pitch, but damn if it isn't compelling.

I'd discounted guix system as a post-nixos option because as an unabashed systemd fan, not having it makes the OS materially worse to live with - not to mention that the rich facilities it provides are increasingly required by the nice desktop environments and such.

... But when framed as "it's not lisp, why would a lisp machine run that"...

danderson,
@danderson@hachyderm.io avatar

I expect GNU Shepherd is still going to drive me nuts in terms of how many nice things I'm used to are missing, but there's been at least one release since I last looked, and maybe the trajectory is something I can get behind.

danderson,
@danderson@hachyderm.io avatar

Inside me this morning, there are two wolves apparently:

"Ugh a bunch of software really sucks to run if you're not on vanilla Ubuntu, not sure it's worth being different"

"You know what might make me happier, an OS that is almost but not quite entirely unlike every other linux-based OS, even more than NixOS"

astrid, to random
@astrid@fedi.astrid.tech avatar

/.well-gnome

danderson,
@danderson@hachyderm.io avatar

@astrid don't forget to set out a little bit of your shell history every day for the well gnome! A displeased well gnome is a significant reliability risk, as they tend to install snapd while you're not looking.

danderson, to random
@danderson@hachyderm.io avatar

> Note: anonymous scopes are not considered scopes.

Once again begging people inventing DSLs to just grab a lisp. Guile is embeddable and everything!

danderson,
@danderson@hachyderm.io avatar

And if you then still want a syntax that's "less weird" or whatever, do feel free to write a separate frontend that produces the lisp as an AST, so long as you still let me use the lisp directly.

With lisp as IR, questions like "how do scopes work" already have good answers, and you can focus all your time on new syntax for list comprehensions, while your users can ignore the weird DSL and use the nice lisp directly. Everbody wins!

danderson,
@danderson@hachyderm.io avatar

"We have lists and list comprehension!"

"Cool, and slice notation right?

"..."

"... And slice notation, right?"

Sigh, C-style for loop it is.

danderson,
@danderson@hachyderm.io avatar

@creachadair The two genders of DSL design:

"My main focus was pleasing syntax, hopefully the semantics work out"

"My semantics allow for concise, orthogonal, elegant expression of entire bottle universes. The syntax is a blend of cuneiform and ancient aramaic script, with a few anatolian hieroglyphs (ca. 800BC form, not the legacy typology) thrown in for readability."

danderson,
@danderson@hachyderm.io avatar

@mcdanlj Well, to a degree. The default for many decades now is lexical scope across all lisps. The CL primitive to mark a name as having dynamic binding is even called SPECIAL! :)

If someone grabs a lisp without learning too much, they're very likely to end up with lexical scoping. And if they do go deeper and learn about dynamic bindings, good for them! Maybe they can make use of this powerful concept in their DSL (or maybe decide lisp seems to have thought of a lot, maybe use it directly!)

danderson,
@danderson@hachyderm.io avatar

@mcdanlj Amusingly I thought of dynamic binding as a CL-ish thing, but turns out no, Scheme's had some dynamic variables since R5RS at least, and R6RS+SFRI 39 and R7RS have explicit facilities for the user to create more.

Conventional style of each remains quite different of course, but it's amusing how the surface diffs are being sanded down, leaving only the fundamental lisp-1 vs. lisp-2 schism :)

danderson,
@danderson@hachyderm.io avatar

@mcdanlj yeah TIL also, dynamic scoping is one of those grubby industrially handy things that I'd expected Scheme to rid itself of. But according to the change, Scheme ended up with a few well known identifiers with dynamic binding behavior (for the usual reasons like stdout redirection), and I guess having special cases felt more icky than having a general dynamic binding facility 🙂 and it seems syntactically noisier to use, which I suspect also means it's used less eagerly than in CL.

danderson,
@danderson@hachyderm.io avatar

@mcdanlj weirdly I think the last holdout on dynamic variables is emacs lisp. Lexical scoping was introduced as a per-file opt in with emacs 24, in 2012! Most modern code turns it on, but for compatibility with the untold decades of elisp that came before, you still have to enable it for every new file. Otherwise, surprise! All dynamic.

danderson, to random
@danderson@hachyderm.io avatar

Extremely niche peeve: when a functional DSL calls something let, but it turns out to be let*.

danderson,
@danderson@hachyderm.io avatar

@vwbusguy It's a lisp thing. let is how you create a scope with new variable bindings, e.g.

(let ((x 5)
(y 3))
(* x y))

declares x=5, y=3 and returns x*y=15.

You can declare many variables in a let block, but they cannot reference each other. Conceptually the values are computed in parallel, x and y spring into existence at the exact same instant.

So you couldn't say:

(let ((x 5)
(y (+ x 2))
(* x y))

because when calculating y's value, x doesn't exist yet.

danderson,
@danderson@hachyderm.io avatar

@vwbusguy let* is a variant of let, in which each variable declaration can refer to prior declarations. So that (y (+ x 2) example above works with let*, and means the same as the C-ish code

int x = 5;
int y = x + 2;
return x*y

But you still couldn't swap the order of x and y in the source code, because then y would be trying to reference x before it was defined.

For that, there's letrec, which allows all variables in the declaration block to reference each other and also themselves.

danderson,
@danderson@hachyderm.io avatar

@vwbusguy The reason these different things exist starts getting into how lisps are implemented and one of the mathematical theories of computing, the lambda calculus. Leaving the formalisms aside (which I'm not the right person to explain), the bottom line is that let is exactly losslessly equivalent to defining an anonymous function and immediately calling it. in python-ish, the example earlier is:

(lambda x, y: x*y)(5, 3)

or more expanded:

def _anon(x, y):
return x*y

_anon(5, 3)

danderson,
@danderson@hachyderm.io avatar

@vwbusguy but hopefully that shows why trying to evaluate y = x+2 in the let form makes no sense. That would be like saying:

def _anon(x, y):
return x*y

_anon(5, x+2)

x isn't defined yet, it only starts existing later on, after _anon starts running.

danderson,
@danderson@hachyderm.io avatar

@vwbusguy So in effect, let and functions have the same semantics: they create a new scope, in which some new variable names exist and have values (the function arguments). let's restrictions on cross-references are a disguised way of saying that you can't use a function's argument name to look up a value, if you're currently outside of the function.

let* on the other hand effectively embodies the concept of closures, nested functions that can see their parent's parameters.

danderson,
@danderson@hachyderm.io avatar

@vwbusguy you can rewrite a let* into a nested bunch of let blocks, in fact:

(let* ((x 5)
(y (+ x 2))
(* x y))

is the same as:

(let ((x 5))
(let ((y (+ x 2)))
(* x y))

The first let makes x come into existence, and within that scope, the second let makes y come into existence. The definition of y can reference x now, because it was made to exist before y.

Translating into lambdas there would be a closure in there, but my head hurts 😂

danderson,
@danderson@hachyderm.io avatar

@vwbusguy Anyway I promise lisp is more fun than this 😂 this is in the weeds of how computer programs even execute, and you can go a long time without caring. But if you do start poking, it's kinda mind-blowing that you can take an extremely restricted mathematical playground with barely any primitives, as you start assembling them in different ways concepts like variable scopes, closures and even sequential execution start pouring out of the math as a result. s'cool!

danderson, to random
@danderson@hachyderm.io avatar

Having a completely normal one, wielding shapes like a "rounded semistadium".

danderson, to random
@danderson@hachyderm.io avatar

The enshittification continues! Premium subscriptions are coming to my spice rack.

danderson,
@danderson@hachyderm.io avatar

@dave_andersen Aptly enough, Garlic Plus turns out to be a weird mix of random shit that nobody was asking for, so that tracks.

danderson,
@danderson@hachyderm.io avatar

@voided So, same as premium subs in tech then

  • All
  • Subscribed
  • Moderated
  • Favorites
  • megavids
  • thenastyranch
  • rosin
  • GTA5RPClips
  • osvaldo12
  • love
  • Youngstown
  • slotface
  • khanakhh
  • everett
  • kavyap
  • mdbf
  • DreamBathrooms
  • ngwrru68w68
  • provamag3
  • magazineikmin
  • InstantRegret
  • normalnudes
  • tacticalgear
  • cubers
  • ethstaker
  • modclub
  • cisconetworking
  • Durango
  • anitta
  • Leos
  • tester
  • JUstTest
  • All magazines