For the best experience on desktop, install the Chrome extension to track your reading on news.ycombinator.com
Hacker Newsnew | past | comments | ask | show | jobs | submit | history | duetosymmetry's commentsregister

Greenspun's tenth rule strikes again! https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule


nah, this is about codebases that are not themselves primarily lisp implementations


This is correct. Greenspun's Tenth Rule is not meant to be interpreted as applying to projects that are consciously creating a Lisp implementation. It's about programs which are not meant to be language implementations at all reinventing ad hoc infrastructure that is designed in Lisps according to established patterns. For instance, badly reinventing something that functions as symbols.


I conjecture the line is not so easy to draw.

If you are creating Lisp because you want to create Lisp, like creating Lisp, want to show off creating Lisp, that obviously is not what the Law is about.

Furthermore, if you create Lisp because you know the Law, know it is inevitable, and want to avoid the caveats and missed bars by doing so explicitly, well then that also is not what the Law is about.

But if you are going about your business, focused on your independent goal, realize you need Lisp like lists, and then 250 lines of code later realize you have created a solid Lisp unintentionally? Well, congrats on falling into the trap but not getting hurt!

Personally, I have created both Lisp and Forth multiple times for suitable projects where I wanted some flexible runtime scripting. I am not familiar with the standard version libraries of either and don’t need them.

Minimal foundation implementations are extremely easy to create, and eliminate any dependencies or sources of mystery.

Anyone know of any other well designed mininal languages?


Except it is been like 60 years that any proper Lisp implementation has more than plain cons lists.


Pretty sure it applies to Common Lisp itself too.


The corollary to Greenspun’s rule is that any sufficiently complicated Common Lisp program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Prolog.


It would be fun if it was "half Prolog, half Common Lisp"


Well, the 'PAIP' book for sure does it, literally.


I've now used both professionally. I look forward to hopefully using both in the same project. Though not holding my breath.


yes but not recursively!


I think that's the joke


A great example of the rule is that C++ rediscovers car/cdr at a glacial pace in the template language. In C++26 one can finally get the car of a typename parameter pack with Args...[0].

I've no idea why they don't introduce car/cdr functions and nil for empty parameter packs and allow to store parameter packs instead of the current syntax insanity.


C++ metaprogramming was done with cons cells already back in '98. The new syntax provides random access instead, which is completely different from linked lists.


Store where?

C++ templates are a lambda calculus, there's no notion of memory cells or state.


In a struct! Pseudo code for extracting the types from subclasses and calling a multimethod on them:

  template <typename Result, typename Head, typename ...Tail>
  struct Foo : Visitor {
    Result res;
    UntypedList lst; // This does not exist!
    Tail... tail;    // This is not possible!
    Foo(UntypedList l; Head hd, Tail... tl) : lst(l), tail(tl) {
      hd->accept(*this);
    }
    void visit(float *f) {
      res = Foo<Result, Tail...>(append(lst, f), tail)::res; }
    }
  };
 
  // Base case that calls the multimethod omitted.
There are two issues here: You can't store the parameter pack in Foo() which is later required by the continuation in visit(). And you would have to use tuples and tuple_cat() instead of UntypedList.

Why can the compiler not infer the types in such an UntypedList? Why is there no car/cdr for tuples?


Not sure what Untyped list is or supposed to do in the above. In fact I'm not sure what the code above is trying to do at all.

If you want a cons-based tuple, boost::tuple will work just fine (or you can implement your own, it is not hard). std::tuple is not (visibly) cons based.


HA!

"Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."

HA HA!


What defines "sufficiently complicated" I wonder? Seems like a shit definition.


That's explicitly encoded right in the rule itself! When the program contains a bug-ridden, ad-hoc simulacrum of half (or more) of Common Lisp, then it has become sufficiently complicated. When it has less than half, it is not yet sufficiently complicated.


It's just a funny observation he made, it's not meant to be a rigorous academic definition :)


"for any sufficiently X the Y" just means that if you don't observe Y right now, just increase the magnitude of X and you'll inevitably reach the conditions for Y to happen.

Famous use of that pattern is Arthur's Clarke "Any sufficiently advanced technology is indistinguishable from magic.". As with OP's quote, this is also vague and imprecise but the point of the idea is that there is a gradient towards which advancements in technology bring us towards a situation where the average person no longer understands how it works and it may as well be magic (while not necessarily defining exactly when does that transition happen)


I like that the "sufficiently complicated" part bothered you, but not the "ad hoc", "informally-specified", "bug-ridden", or "slow" parts.


No, I think it's pretty fair. One could argue about these, but except for "slow" these are more quality qualifiers, rather than quantity. So you either agree it's "bug-ridden" or not (i.e. the number and seriousness of bugs in it is negligible by whatever standards). And I think even "slow" can be discussed in the same manner, the actual speed is quantitative, of course, but in the end one either argues that this speed is "slow" or isn't. So, given some rhetoric skills of your opponent it's at least possible for that statement to be proven false, if he convinces you the implementation actually isn't slow nor bug-ridden, or at least if there's no Lisp-implementation indeed.

But what is "sufficiently" complicated? Now it's a silly statement that just doesn't pass Popper criterion: even if nobody dares to deny your program is complicated, one can always say it isn't sufficiently complicated, hence the fact it doesn't contain Lisp-interpreter disproves nothing. A man of culture wouldn't use such definitions.


Isn’t that sort of the point? It makes the argument impossible to dispute. If it’s not slow or big-ridden, then it’s just not sufficiently complicated. Which you’re correct to call out.

I think what makes it work is that Common Lisp very quickly becomes a faster way to do things because of how insanely efficient it is.


A man of culture would never refer to an epigram as a definition.


Which culture? What about women? What a strange comment.


The rule defines it tautologically. Which is sufficiently unambiguous for its purpose!


Greenspun's tenth rule, corollary: Any sufficiently precise definition of "complex system" contains an ad hoc, informal, bug-ridden, slow specification of half of Common Lisp.


My experience is: once you have enough different FSM and reducers that you need to abstract them, the 'sufficiently complicated' criterion is made.


Hi, yes, it's open source. My web site's github repo is at https://github.com/duetosymmetry/web-site/tree/customization . The JS for controlling the web toy is at https://github.com/duetosymmetry/web-site/blob/customization... . This relies on a modified version of Polynomial.js which I will hopefully get accepted upstream, but for now it's just on my fork at https://github.com/duetosymmetry/Polynomial.js/tree/Aberth (though this is also behind my local repo).


I wanted to keep the UI from getting too busy, which is why I limited the degree to 7. But if somebody really wants to play with higher-degree polynomials, I'm not going to stop them!


I was just pondering about this. I imagine that moving a coefficient a small amount (and so long as the roots are not too close) that Newton-Raphson, initialized with a previously-known root, would converge very quickly to the new root while preserving the order.

If there truly are roots of multiplicity >= 2, then preserving the order of the multiple roots doesn't matter. Another issue is that Newton-Raphson might fail if the roots are too close.


That's the one in our galaxy, and the other target—in the galaxy M87—is around 5 billion times the mass of the sun!


I believe every radio telescope has their own reference clock that lives at the site. The EHT team is not responsible for schlepping these clocks around. There are other reasons besides VLBI to have really good timing at the site—for example, pulsar timing.


I think there was a question about that: they had some issues with two different standards and decided it was better to pick one type and use that at all locations even if they had to bring it up themselves.


> fixed-length binary strings are a group where the operation is xor (or '^') and inv(x) = x

Most people would call this group (Z/2Z)^n, i.e. n copies of Z/2Z under addition. Similarly, for "matrix addition" you could say Z^(mn) or R^(mn) for matrices with dimension mxn with elements Z or R (or whatever you are filling your matrices with). Your only non-abelian example is matrix multiplication, i.e. GL(n,R), general linear transformations of dimension n over R. It may or may not be interesting that this is mainly focused on abelian groups.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search:

HN For You