• 0 posts
  • 25 comments
Joined 3 years ago
Cake day: June 11th, 2023
  • If your security relies on a password, you will always be anxious that somebody, somewhere, has somehow figured out what it is and already has access to your bank account.

    No I won’t. All my passwords are something like I0!2b6KJ!eA04WiJ&&MFToCQ7CN*4mvb and each is used for only one thing because I’ve been using a password manager for over a decade.

  • There’s a reason Linux on a Thinkpad is a meme.

    You haven’t said much concrete about your requirements, use case, or budget, so I don’t have a recommendation much beyond whatever Thinkpad meets your requirements. The “serious” models in the T, P, and X series tend to be preferable to the others.

    I love mine!

  • I read the article, and I think DickHertz’s comment is pretty much right. The article’s example illustrates the point:

    For example, Inc. columnist Jason Aten recently discovered that Meta’s Muse AI assistant somehow had synced his entire local Messages database and was using those messages as context for its tasks.

    Aten did not understand that the Messages database is stored on the disk (presumably) unencrypted and readable by anything with full disk access. He got a result he didn’t want because he did not understand the implications of granting that permission, and Apple seeks to add more friction to the process to protect users from making that mistake.

  • I was tempted, but nobody learns anything from that.

    I have the impression the author of the article has dabbled with Lisp but hasn’t actually set up a reasonable development environment and written something non-trivial. That’s not a great position from which to write critiques of a language.

  • To add to the point about homoiconicity, both the article and my toplevel comment mention thread macros. The article talks about them being equivalent (syntactically at least) to method chaining, which I agree with.

    The thing is, to get method chaining, the language has to have an object system, and the functionality you want to use has to be written in an object-oriented style. To get a thread macro, you need ten lines of code (aside from the docstring and metadata).

  • Yes. Well, sort of.

    The actual quality is homoiconicity, meaning that code in the language is represented in the language’s own data structures (beyond the entire source file being a string). This enables structural macros - using the language to manipulate code before execution.

    Some languages have tried to do this without the language syntax actually being data structure literals. Rust does it, but a typical Lisp macro looks like a simple template where some things are marked to happen at compile-time and others get spliced in at runtime. Rust macros don’t beyond the most trivial examples.

  • The first example actually has more bracket pairs (7) for Javascript than for Lisp (6). Rainbow bracket modes for editors can help when bracket matching is an issue.

    This example which suggests counting parens is also solved by rainbow brackets, and/or editor tooling like paredit-mode that won’t even let you type mismatched brackets:

    (f (g (h (i (j)))))
    

    And in most modern Lisps, one might use a thread/pipeline macro instead:

    (-> (j) i h g f)
    

    With mixed nesting, Lisp programmers often use newlines to improve clarity:

    (aap noot ((mies wim) zus) (jet teun vuur))
    

    becomes

    (aap noot
         ((mies wim) zus)
         (jet teun vuur))
    

    A later example in the post does that:

    (sum
      (filter
        (split (read (open "input.txt")
                     ",")
        (lambda (it) (> it 0)))
    

    Which makes one of the errors it contains clear: “,” should be an argument to split, but here it is an argument to read. It is aligned with the start of the first argument to read, so that’s very visible. There are also two levels of unclosed parens. Pasting it into an editor made that clear instantly.

    This version is correct:

    (sum
     (filter
      (split (read (open "input.txt"))
             ","))
      (lambda (it) (> it 0)))
    

    But I’d probably write this with a thread macro:

    (-> (open "input.txt")
        read
        (split ",")
        (filter (lambda (it) (> it 0))))
    

    It’s possible to write unreadable Lisp, but people who are good at Lisp don’t. This is true of most languages.