Kragen Javier Sitaker writes personal essays and experiments on programming languages, compilers, bootstrapping, memory models and small computing projects.
Commenters recommend his work on bootstrapping, the Egg of the Phoenix, and his memory models essay as ways to understand how languages like C relate to hardware.
> I don't think your revision of the "S-expression" grammar is in accordance with the normal use of the term; it says ()() is an S-expression, when conventionally it's considered to be two of them. If that's what you want, then adding the outer *() is fine, but you should probably drop the leading * on the recursive call *ex, because otherwise the grammar is ambiguous.
You're totally right, sorry! It's an important aspect of S-exps that I overlooked. I forgot that a typical Lisp file is not a valid S-expression, but a concatenation of a bunch of them. Plus maybe some whitespace/comments prepended.
So an S-expression syntax, as normally defined, is not closed under concatenation like Jevko.
To solve that (assuming it's a desirable feature as I do) purely syntactically, without talking about the REPL, you'd need another top-level syntax.
So why not simplify things and make one that meets this criterion by itself?
Which makes me think of another aspect where Jevko is simpler.
The restrictions Jevko puts on a unicode sequence are that the escape character must be followed by itself or a square bracket and that unescaped square brackets must be balanced.
This is pretty much an exhaustive one-sentence description that would allow you to validate or generate a Jevko.
A similarly simple description is impossible to state for S-expressions.
I tried and I came up with (for your minimal defnition of S-exp):
The restrictions S-expr puts on a unicode sequence are that it must…
BTW I remember your "memory models" post from a few years ago, and I found it insightful! It got me thinking about many related things.
http://canonical.org/~kragen/memory-models/
Around that time I'd noticed that the stringly-typed languages of shell, awk, and make have no garbage collection. They're value oriented and not reference oriented. The goal of Oil was basically to "upgrade" shell into something more like Python, and on the surface that looks straightforward, but the reference model vs. value model makes it pretty different.
I've gone back and forth on that... whether I should just slap GC into a shell, or whether I should try to preserve the value model while making it less stringly-typed and more expressive.
I have a more ambitious idea for a language where every value is essentially a pair (Go-like string slice, structured data), but I probably won't get to that in the near term. For a concrete example, I noticed from writing some HTML processors that both DOM and SAX APIs have a bunch of flaws for processing semi-structured text.
-----
Also, on the other point, let's consider these two possibilities about Chez / Dybvig:
1) Dybvig is an average programmer who got "superpowers" from Lisp, i.e. got a 10x boost in productivity.
2) Dybvig and Chez are an outlier, e.g. like Fabrice Bellard and his recent QuickJS (and other projects), or Lattner and LLVM/Clang/Swift. The salient point is that these projects have nothing to do with Lisp.
It's obviously…
You are against Easter Eggs, I gather? ;)
More seriously, of these two implementation for Python's str.lower(), which is "minimal"?:
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(s[i]);
if (isupper(c))
s[i] = _tolower(c);
}
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(s[i]);
s[i] = _tolower(c);
}
I suspect most would say the second is minimal, but the first is what Python uses, because it's measurably and distinctly faster than the second, and that extra performance is worth the extra maintenance overhead.
That's one reason I believe that programming-as-art metaphors don't really apply. Minimalism as an art form not the same as minimizing the cost function of different uncertain factors.
Anyway, this reminds me of a story from the Tao of Programming, http://www.canonical.org/~kragen/tao-of-programming.html :
There was once a programmer who was attached to the court of the warlord of Wu. The warlord asked the programmer: ``Which is easier to design: an accounting package or an operating system?''
``An operating system,'' replied the programmer.
The warlord uttered an exclamation of disbelief. ``Surely an accounting package is trivial next to the complexity of an operating system,'' he said.
``Not so,'' said the programmer, ``when designing an accounting package, the programmer operates as a mediator between people having different ideas: how it must operate, how its reports must appear, and how it must…
> This sounds really interesting!
Cheers!
> I'm happy my article was helpful to you.
It was just the thing! Very helpful. Thank you for writing it.
> I really like how your notebooks integrate (judiciously chosen)
execution trace display with explanation. I think this is something
literate programming benefits a lot from.
Cheers again. I find those traces aesthetically pleasing in and of
themselves. I can imagine a (strange, niche) art gallery that had large
prints of them on display. Jupyter notebooks have so many good things
going on. (Not that they're perfect, but they hit a sweet spot IMO.)
> I wonder if there's a way to include a smooth gradient from specific
examples like your V('80 P') to more general cases, either with abstract
interpretation or a Bret-Victor-style overwhelming battery of data
points.
I'm sure there is, there are so many possibilities. Just the traces
alone could be animated or made into (partial) graphs (have you seen
http://pythontutor.com/ ?)
Concerning abstract interpretation, if you squint a little,
the Prolog code already does that. Markus Triska suggested using the
CLP(FD) integer constraints for the math primitives, which was brilliant,
so it's doing a kind of abstract interpretation. You can give it a
completely general stack "type" (just a logic variable) and it will tell
you, e.g. '+' is:
int(A), int(B) -> int(A+B)
and so on. It's also pretty easy to replace the main operators to get a
different (but related)…
You've mentioned this before, here:[1]
https://news.ycombinator.com/item?id=5549627 (2013)
There you link to writing of your own from 1997, "Real News":
http://www.canonical.org/~kragen/real-news.html
A book that explores some of these concepts (in terms of the Net's impact on traditional news media) is Andrew L. Shapiro's book The Control Revolution (1999).[2]
What numerous prognosticators (yourself, Epic, Shapiro, and more) got right was that the traditional print media would be profoundly disrupted. What seems to have been broadly missed was that digital, algorithmic media would allow for individual targeting and manipulation, if not by the publishers or platforms themselves then by those who exploited them, either in partnership or as hostile attackers.
________________________________
Notes:
1. Not stalking, honest! I was looking for this particular comment to come back and respond to it.
2. Not to be confused with James Beniger's similarly-titled 1986 book. Shapiro does reference it, both are well worth reading. Shapiro's is far more politically-conscious.
Shapiro's: https://www.worldcat.org/title/control-revolution-how-the-internet-is-putting-individuals-in-charge-and-changing-the-world-we-know/oclc/43719224
Beniger's: https://www.worldcat.org/title/ltltthegtgt-control-revolution-technological-and-economic-origins-of-the-information-society/oclc/1283256258
I've had the same experience as Tesla, though not so extreme as to cause problems. For as long as I can remember I have enjoyed extremely detailed "daydreams" where I explore worlds and meet people inspired by the books I read. I suspect this is fairly common in children, but I did it right through high school, university, and several years in the workplace.
The real question is: how much benefit does having a strong and well exercised imagination have for a technical career? (I assume it's very useful for artists).
I've found that software development gets a large boost. The more of the design you can hold in your head on once, the better the coder is able to anticipate the consequences of their decisions. When debugging, the programmer is able to see the entire state of the application that must have predicated it, experiment with a range of fixes, all before writing any code.
I love this quote from The Tao of Programming[1]: "Sometimes there are difficult problems. I see them coming, I slow down, I watch silently. Then I change a single line of code and the difficulties vanish like puffs of idle smoke."
[1] http://www.canonical.org/~kragen/tao-of-programming.html