Artexias
Artexias

Reputation: 335

Sbcl "Function Undefined"

I'm fairly new to common lisp and have been doing Exercism exercises to get into it.

I'm using debian on wsl2 on windows 10.

I have sbcl 2.1.1 with quicklisp

Here is the file I'm trying to load

(defpackage :lillys-lasagna-leftovers
  (:use :cl)
  (:export
   :preparation-time
   :remaining-minutes-in-oven
   :split-leftovers))

(in-package :lillys-lasagna-leftovers)

(defun preparation-time (&rest rest)
  (* 19 (length rest)))
 


(defun remaining-minutes-in-oven (&optional (opt :normal opt-provided))
  (if opt-provided (cond
                     ((eql opt :shorter) 337)
                     ((eql opt :very-short) 137)
                     ((eql opt :longer) 437)
                     ((eql opt :very-long) 537)
                     (t nil))
      opt))

Aside from the issues which could arise if the second function is incorrect. I have tried loading the above file in two ways

  1. By entering sbcl and using

    (load "test-file-name")
    
    (preparation-time 1 2 3)
    
  2. By loading the file into sbcl

    sbcl --load "test-file-name"
    
    (preparation-time 1 2 3)
    

In both cases I get

CL-USER(1): (preparation-time)
; in: PREPARATION-TIME
;     (PREPARATION-TIME)
;
; caught STYLE-WARNING:
;   undefined function: COMMON-LISP-USER::PREPARATION-TIME
;
; compilation unit finished
;   Undefined function:
;     PREPARATION-TIME
;   caught 1 STYLE-WARNING condition

What am I doing wrong? I want to have a way in which I can test my code locally.

Upvotes: 2

Views: 219

Answers (2)

Xach
Xach

Reputation: 11854

When you write a symbol without a package prefix, the reader uses the current package (and other reader settings) to decide what symbol it refers to. When you start SBCL, the current package is named CL-USER.

Your function is named by the string PREPARATION-TIME in a package named LILLYS-LASAGNA-LEFTOVERS. If you are in the CL-USER package, and you want to refer to it, you can do this:

  • (lillys-lasagna-leftovers::preparation-time 1 2 3) - this will work on symbols regardless of their external status
  • (lillys-lasagna-leftovers:preparation-time 1 2 3) - this syntax with only one colon works because you used :export to make the symbol external

If you'd like to refer to preparation-time without a package prefix, there are a few options:

  • (use-package :lilys-lasagna-leftovers) will make the current package inherit all external symbols, which includes preparation-time - this can fail if a different, non-eq symbol is already accessible by the same name
  • (import 'lilys-lasagna-leftovers:preparation) will make that symbol present in the current package, so it can be referred to without a prefix - this can fail if a different, non-eq symbol is already accessible by the same name
  • (shadowing-import 'lilys-lasagna-leftovers:preparation) will make that symbol present in the current package, and additionally override any previously accessible symbols with the same name
  • (in-package :lilys-lasagna-leftovers) will change the value of *package* so symbol lookups without a package prefix are relative to your package

Of all these options, if I were working on this project, I would most likely use in-package. The other options have their most appropriate uses as well, but you can usually start with in-package and move on to other things as the need arises.

Upvotes: 6

Rainer Joswig
Rainer Joswig

Reputation: 139251

Use

(lillys-lasagna-leftovers:preparation-time)

The function PREPARATION-TIME has been exported from package LILLYS-LASAGNA-LEFTOVERS.

Upvotes: 3

Related Questions