Search code examples
common-lisp

Why I am getting PACKAGE-LOCKED-ERROR when trying to use function in alexandria package?


I don't understand why this is throwing an error at all. Please explain why this would be and how I can clear this unexpected blockage. Thanks.

CL-USER> (alexandria::starts-with-subseg "cat" "catdog")
; Debugger entered on #<PACKAGE-LOCKED-ERROR "interning ~A" {10059DE253}>

Lock on package ALEXANDRIA.1.0.0 violated when
interning STARTS-WITH-SUBSEG while in package COMMON-LISP-USER.

(edit) just realized it's a bad function name. But still, what am I missing?


Solution

  • If Alexandria hadn't put a package lock, you would see a more common error message:

    The function ALEXANDIRA::BAD-FN-NAME is undefined.
    

    But they put a lock:

    (defpackage :alexandria
      (:nicknames :alexandria.1.0.0 :alexandria-1)
      (:use :cl)
      #+sb-package-locks
      (:lock t)
      …
    

    Now you first saw this lock error, but look further and see the available restarts:

    
    Restarts:
     0: [CONTINUE] Ignore the package lock.
     1: [IGNORE-ALL] Ignore all package locks in the context of this operation.
     2: [UNLOCK-PACKAGE] Unlock the package.
     3: [RETRY] Retry SLIME REPL evaluation request.
     4: [*ABORT] Return to SLIME's top level.
     5: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1007D29B63}>)
    

    Choose the 0 to ignore the lock, and you'll now stumble on the "undefined function" error.

    But now, go back to your REPL, and try to autocomplete the bad function name: you can O_o This is not so great, actually. When you call a function, or simply try to evaluate a symbol with the Lisp interpreter, your Lisp first "interns" (creates) this symbol into the corresponding package. It is now "bound" and it will stay around unless you "unbind" it with makunbound.

    Alexandria developers took a defensive approach, and that's good because Alexandria is an important piece of the CL ecosystem. You don't want to change its bindings by error. Imagine doing, by inadvertance…

    (defun alexandria:starts-with-subseq () 
       :AHAHAH)
    

    But you can't, you get the package lock error! Thank you, Alexandria.

    Lock on package ALEXANDRIA violated when
    setting fdefinition of STARTS-WITH-SUBSEQ while in package CL-USER
    

    you can of course carry on with the restart, but you've been warned.


    http://www.sbcl.org/manual/#Package-Locks

    ps: you only need 1 colon when calling a function: alexandria:foo and not ::.