HNHacker News
TopNewBestAskShowJobs

kbp

807 karma · joined October 19, 2016

submissionscomments
kbp··on Working remotely, 4 years in
> The person who corrected the original commenter seems to recognized that "he" was being used in a gender-neutral way and even offered the use of "they"

Their first suggestion was to use the correct gender-specific pronoun, and then they said that alternately a gender-neutral one could have been used. I don't think it was understood as gender-neutral.

> The fact that we can find another word that unambiguously removes gender from the subject means that gender is irrelevant to the comment in question entirely

Sure, but if it's read as gender-specific then it's still a factual mistake. Would you be so defensive about someone correcting a wrong, but not critically important, date?

kbp··on Working remotely, 4 years in
> Even if you accidentally parsed "he" as referring to the male gender at first, the context surrounding the comment would quickly clarify that misunderstanding and reveal that the comment was written in a gender-neutral form.

I don't see why it isn't just as likely for someone, like the person who corrected the use of "he," to decide from context simply that the poster was mistaken about the person's gender, and to treat it like they'd treat any factual mistake. Language is about conveying messages to people, and part of the message that was received was that ratsimihah believed the author to be a man. Grammatically acceptable or not, using "he" as a gender-neutral pronoun here introduced confusion.

kbp··on What Made Lisp Different (2002)
I think your version of "fun" is my version of "proper abstraction and factoring".
kbp··on What Made Lisp Different (2002)
> The zip family has more names than just `map`, but boilerplate? You have to select the right name for your code but you don't have to select more names.

Well, you have to select one of the zip functions in addition to map. Those are more names.

> Also, Haskell has an `apply` function. It's the `$` operator

That isn't what apply does. Apply takes a function and applies it to a list of arguments, (f x y) is equivalent to (apply f (list x y)).

kbp··on What Made Lisp Different (2002)
> Clojure is a Lisp. One of the distinctive things about Lisp is that it has dialects.

When one of those dialects is completely source-incompatible with every other dialect (the rest of them share non-trivial programs freely), and doesn't share the same core features as every other dialect (like list structure), then why is it still a dialect and not a different language? Calling all the other Lisps that share core features and run the same code different versions of one language makes sense to me; I don't see the point in applying it to any language that borrowed a couple ideas.

If I have a large codebase written in (any) Lisp, will porting it to Clojure be significantly easier than porting it to Javascript or Ruby or any other modernish language? Not really; it's a complete rewrite either way. That sounds to me like it might just be a different programming language.

kbp··on Just what does “code as data” mean anyway? (2014)
> Regarding the loop: that's exactly what I described, you just move lines and fix the indentation.

The experience you get with Paredit is not the same experience you get with C and vi, because you have to be concerned with things at the character level to make the transformation. What single command do you use to move the function call, for loop, label, or do-while loop after the closing brace of the current block into this block, whether it's 1 line or 100? What if you have something like f(x, y * 2) and you decide that you want to put y * 2 into a variable instead? Do you write every argument to every function on its own line?

Again, if you want to do things the C way in Lisp, it's not like Lisp makes it hard to do those kinds of edits. Things like Paredit are popular because people find them more efficient to use. Editors can support Paredit-like editing in C, but it's much more difficult to accomplish because of limitations with C's syntax.

kbp··on Just what does “code as data” mean anyway? (2014)
> I see no reason what you just gave isnt isomorphic to

> sum(1,2,sum(3,4))

> Which is not "code as data"

Says who? In Prolog it would be. Whether or not some syntax is a data structure literal depends entirely on the syntax of your language. Your example is isomorphic if you make the corresponding change to your language's data structure literals.

kbp··on Just what does “code as data” mean anyway? (2014)
Sure there is. Imagine you had this function:

    int f(void) {
        int x = 1;
        return x * 2;
    }
Then pretend that later you wanted to call f and provide your own value of x for it to transform, but you realise that f doesn't take a parameter, so you go to move the x declaration in f into its parameter list. What you really want to do here is delete the first element of the parameter list, and then move the first expression in its next sibling list (the function body) to the end of it. C syntax doesn't make this easy for editors to do, but the operations can still be thought of in terms of lists.

You get nested expressions whenever you use if or a loop or call a function. C programs might be flatter on average than Lisp programs, but there's still plenty of structural editing you could do. Another example is moving an expression out of or into a loop, without concern for how many lines it takes up, whether it's a function call or a loop or anything.

The difficulty that C syntax creates for editing operations like this isn't C not having the need for Paredit-style editing, it's C not having good support for it.

kbp··on Just what does “code as data” mean anyway? (2014)
> I kept reading places that lisp macros and c macros were completely distinct, which seems untrue after a couple years of trying clojure.

They're similar in that they're both compile-time functions that generate code, but they're very different in practice, because C macros are written in a text substitution language that knows virtually nothing about C, which naturally makes writing even simple macros very error-prone. Lisp macros, on the other hand, are written in plain old Lisp and receive regular Lisp data structures that you can use the whole language to operate on.

A lot of people learn from C that macros are very difficult to get right, so it's important when they move to Lisp that they give them a second look, because Lisp is a much more capable language for code transformation than cpp.

kbp··on Just what does “code as data” mean anyway? (2014)
> I don't disagree that if all you have is parens, then you want something like paredit. But for a C programmer there is no need for such a thing.

If that's a good selection of tools for editing code, then why would Lisp programmers need Paredit? Most of those commands work just as well for editing Lisp. The advantages that Paredit gives over that model are semantic commands rather than character based ones, things like easily slurping and splicing things into parent lists (a block, the arguments to a function call, whatever) without having to think about the syntax needed for that transformation.

There's nothing about Lisp that makes the vi commands you use for editing C less useful for editing Lisp; people use things like Paredit because they allow for a much more semantic style of editing.

kbp··on S-Expressions (1997)
> The biggest practical improvement that I've seen was Clojure notation that expands the number of data literals to include vectors, maps, and sets.

Common Lisp has literal syntax for vectors (and it wasn't the first Lisp to). Its standard representation of a set is just a list, but if someone were to add proper sets to the language they could add read syntax for them easily

CL also has read syntax for maps (as has every Lisp) in the form of alists; it doesn't have literal hash tables, but those aren't terribly useful. Alists perform better for lookup for less than 20 or so keys (their writes are always constant-time), and they aren't going to be a bottleneck until you have at least several hundred keys, at which point you probably won't be writing those as literals in your source code. As well, alists have several other nice properties over hash tables, like not being tied to any equality predicate.

Alists are a standard Lisp map with literal syntax that's been around since the beginning and are often preferable to hashes, but if you really did want hash literals specifically, it's a trivial read macro.

kbp··on VS Code to autocomplete JavaScript class 'this' properties automatically
In ReasonML, most of your code is just Reason (which is just OCaml), but you can easily provide type declarations and use Javascript code in a typesafe way, or you can just drop to raw JS at any point in a Reason file.
kbp··on Perl 6 Optimism
It has optional static typing:

    > sub f(Int $x) { $x + 1 }
    sub f (Int $x) { #`(Sub|140221097113944) ... }
    > sub g(Str $x) { f($x) }
    ===SORRY!=== Error while compiling:
    Calling f(Str) will never work with declared signature (Int $x)
kbp··on Sound and fury: how pronunciation provokes passionate reactions
> the accepted pronunciation of various tech project names

Resque (where the readme says in the first sentence that it is pronounced like 'rescue') always bugged me. Are there any English words where 'que' at the end of a word like that makes a 'kyoo' sound? Would 'resqueue' have been such a horrible spelling?

kbp··on Howl: a nostalgic homage to the brief, hazy era of “pure” London punk
> Music is no longer a social movement. Back in the day being a fan of the Clash went far beyond music you were joining a social/political movement, something you believed in. Katy Perry might sing a catchy tune but its all about her personal ego

I don't think the Clash ever had the kind of mainstream success that someone like Katy Perry has. A more appropriate analogue for "back in the day" would be like Andy Gibb or someone.

kbp··on Antique BeOS Content by Scot Hacker (2011)
> 18 years ago. Perl and Python.

Perl 18 years ago is pretty standard.

kbp··on The Origin of CAR and CDR in Lisp (2005)
> No one claimed Hickey invented first and rest, or even implied it.

I think that saying "This is why Clojure has first instead of car and rest instead of cdr" is a very odd way of saying "this is why Clojure doesn't have car and cdr" if you don't mean to imply that it added first and rest.

I also think the originally linked article was rather poorly written and seemed to put all of the focus on "car and cdr sure are weird names" without examining that they are operations on cons cells, which Clojure doesn't have. Clojure leaving out the names car and cdr doesn't really have anything to do with those names; it left out the data structure they operate on. A language without numbers proably wouldn't have a sqrt function either, but that has little to do with the clarity of the name sqrt.

Discussing the differences and tradeoffs between how Lisps and Schemes all represent lists compared to how Clojure does (and the tradeoffs with how Clojure makes up for the other things that conses are used for in Lisp) might have made for a more interesting point, but it would have been a harder one to make than just pointing at two not immediately obvious symbol names (without even mentioning that it did keep the equally archaic and unhelpful name "cons" but changed its behaviour).

kbp··on The Origin of CAR and CDR in Lisp (2005)
> We do have it, it is called "elt" in Lisp.

In Common Lisp, ELT is generic over sequences, so it also works on arrays. CL also has a function actually called NTH which is specific to lists; NTH was also in Maclisp, Lisp Machine Lisp, etc with the same meaning (Interlisp had an NTH function but it's what Common Lisp calls NTHCDR (except that Interlisp NTH used 1-based indexing whereas CL NTHCDR uses 0-based)). Emacs Lisp uses the same nth/elt distinction as Common Lisp. Islisp has elt which is generic over sequences, but I believe that it discarded nth.

kbp··on The Origin of CAR and CDR in Lisp (2005)
Oh, sorry, the linked story used to be different. I hadn't noticed it was changed.
kbp··on The Origin of CAR and CDR in Lisp (2005)
That is cool, but I was wondering if you had a citation for Steve Russell coining the names? I don't believe that's true.
kbp··on The Origin of CAR and CDR in Lisp (2005)
> The 90% case here is "second", "third", etc.

In addition to first and rest, Lisp has provided second, third, fourth, etc since the 70s, as well as the more general nth/elt which just takes the index as an argument.

> there are other naming conventions that would be more readable. You could use "h" and "t" for head and tail, or "l" and "r" for left and right

Why would you bother replacing names with 60 years of precedent with h and t so that instead of cdaddr you could write thtt? I think cdaddr nonsense is illegible and very bad style, but I don't see how someone could seriously suggest writing thtt as a good solution to that readability problem. The real solution is to use named accessors instead of ad-hoc pointer chains.

kbp··on The Origin of CAR and CDR in Lisp (2005)
> It is entirely possible that the unwillingness of the Lisp community to give up in this obscure terminology in favor of something more user friendly contributed to its demise.

What more-user-friendly terminology do you suggest?

kbp··on The Origin of CAR and CDR in Lisp (2005)
> If you want precise names to offer as aliases to "first" and "rest", then I think ML-style "head" and "tail" are better names than "car" and "cdr".

I don't know what you mean by ML-style, as most ML-derived languages call car and cdr fst and snd; I don't know any that call them head and tail.

But aside from that: really? I think of head and tail as being basically synonymous with first and rest (every language I know of that has built-in head and tail functions, or that idiomatically uses head and tail or abbreviations for variable names, uses them to mean the first element, and the list beyond that element. I don't know any that use them for two parts of a 2-tuple). The left child of a binary tree node being the head and the right side being the tail makes no sense at all to me. Not that car and cdr shouldn't be aliased when they're being used that way, but reading as "element a" and "element b" is better to me than "head" and "tail" which are equally meaningless, but by having English names imply meaning.

Lisp offers (since the 70s) the aliases first and rest for when conses are being used as lists, and I think those are fine and should be used when you are operating on lists. Conses can be used as other things than lists, though, and first/rest (or head/tail) don't work as meaningful names for any usecase aside from lists. Head/tail are totally equivalent to first/rest to me and I don't really care which pair is used for naming the list-handling functions, but they're both bad sets of names for the cons handling functions.

kbp··on The Origin of CAR and CDR in Lisp (2005)
> car and cdr worked for Lisp because, during the '70s, Lisp as a whole was novel enough to gain a sizable following. It doesn't work today. (And note that, even then, Lisp lost a lot of potential users due to the S-expression based syntax.) I'm firmly in the "first" and "rest" camp

first and rest are bad names for what car and cdr do, in the general case. If you have "Jenny" mapped to "867-5309" in a dictionary, then getting the "Jenny" part of that binding with first and the "867-5309" part with rest doesn't really make any sense. Similarly, if you have a node in a binary search tree, getting the subtree with the lesser elements with first and the subtree with the greater elements with rest also doesn't make any sense.

Lisp, even in the 70s, uses first and rest as synonyms for car and cdr for the case where you are operating on a list. first and rest do not make sense as replacements for car and cdr in the general case, however, and if all you want is to have them as synonyms for when they do make sense, then Lisp has been providing that since the 70s.

kbp··on The Origin of CAR and CDR in Lisp (2005)
I think that's more attributable to the fact that for most people, their first 10 hours with Lisp are spent writing recursive functions that explicitly cdr down lists, rather than the names car and cdr. I think it would make a much bigger difference if more people's first exposure to Lisp was something like:

    (with-open-file (input "foo.txt")
      (loop for line = (read-line input nil)
            while line
            do (write-line line)))
But instead most schools only use Lisp as a vehicle for teaching the basics of recursion and functional programming, rather than as an immediately useful tool, so most students go away with the idea that that's what Lisp is used for, and attribute their difficulty understanding The Little Schemer to difficulty understanding Lisp.
kbp··on The Origin of CAR and CDR in Lisp (2005)
> Both seem better to me, as they have some meaning other than random made up strings (for people who don't use 704).

Calling the lefthand child of a node in a binary tree the "first" and the righthand child the "rest" seems like a markedly worse naming system than random made-up names, to me, because the use of English names seems to be implying meaning that it doesn't really offer.

The idea of a thing with two values, one on the left side and one on the right side is probably a bit more intuitive, but I really doubt it's that much moreso than just saying it has two parts called the car and the cdr. People who've never touched a 704 have been learning about conses as a data structure with two parts, a car and a cdr, for almost 60 years; to most of them, it's just vocabulary you learn now, the same way that numerator and denominator are just arbitrary names to people learning fractions.

I also think it's interesting how much people complain about car and cdr yet it's very rare that people complain about cons, which is just as badly named. It should probably have been called make-pair or something, which I think is a much bigger improvement than car vs lhs. But really, it's 3 words of vocabulary, whose definitions can be completely understood by

    (car (cons x y)) = x
    (cdr (cons x y)) = y
That's not very much to ask someone to wrap their head around, it was meaningful to the original implementors, and for people now there's about 60 years of precedent for using that terminology.
kbp··on The Origin of CAR and CDR in Lisp (2005)
> I assert that naming the interface for the implementation is almost always the wrong thing to do.

I think it's perfectly acceptable if there aren't really any better names for the abstraction you're creating. car and cdr work just fine as made-up arbitrary names for an abstraction that doesn't really have any more natural names for them; the fact that 60 years ago they weren't actually entirely arbitrary doesn't really change that.

kbp··on The Origin of CAR and CDR in Lisp (2005)
> Something other than CAR/CDR would have been a better choice for working with CONS cells, even back in 1959.

> Are the names less than optimal? Yes.

I don't think that's self-evident. The only better alternatives I've ever heard suggested are something like left and right, which I think are probably slightly clearer names for what the functions do, but not significantly so (I don't think "a cons is a thing with a left and right side" is that much more intuitive than "a cons is a thing with two parts called a car and a cdr").

Further, I think in 1959 when most everyone using Lisp was hacking on the implementation itself, names that are mnemonic for what the machine they were actually using is actually doing make sense; I don't think they're clearly sub-optimal now, but I think they were even less so in 1959.

kbp··on The Origin of CAR and CDR in Lisp (2005)
As noted earlier, the names first and rest date from the 70s and were already around in Lisp Machine Lisp. Also, to nitpick: in Racket, first (car) will sometimes throw when used on lists, too, if the list happens to be the empty list (which has been true for decades in Scheme). It's more correct to say that it throws when used on non-pairs/conses (aka atoms).
kbp··on The Origin of CAR and CDR in Lisp (2005)

    Date: 5 March 1980 08:54-EST
    From: Mark L. Miller <MILLER at MIT-AI>
    To:   Dave.Touretzky at CMU-10A, RWK
    cc:   KMP, HIC, BUG-LISP
    Re:   CAR and CDR
    
    Of course, you could rename them to, e.g., "LHS" and "RHS" for "Left Hand
    Side" and "Right Hand Side".  This would address the composition argument
    in favor of CAR and CDR: CADR -> LRHS (left-hand-side of right-hand-side),
    CDADADR -> RLRLRHS, and so on.   It's easy to provide these as macros.
    
    Later, you can explain that the original names are CAR and CDR, and isn't
    that silly, etc.
         Regards, Mark
← PreviousPage 7 of 12Next →