Skip to main content

intern

intern Function

Syntax:

intern string &optional package → symbol, status

Arguments and Values:

string—a string.

package—a package designator . The default is the current package.

symbol—a symbol.

status—one of :inherited, :external, :internal, or nil.

Description:

intern enters a symbol named string into package. If a symbol whose name is the same as string is already accessible in package, it is returned. If no such symbol is accessible in package, a new symbol with the given name is created and entered into package as an internal symbol, or as an external symbol if the package is the KEYWORD package; package becomes the home package of the created symbol.

The first value returned by intern, symbol, is the symbol that was found or created. The meaning of the secondary value, status, is as follows:

:internal

The symbol was found and is present in package as an internal symbol.

:external

The symbol was found and is present as an external symbol.

:inherited

The symbol was found and is inherited via use-package (which implies that the symbol is internal).

nil

No pre-existing symbol was found, so one was created.

It is implementation-dependent whether the string that becomes the new symbol’s name is the given string or a copy of it. Once a string has been given as the string argument to intern in this situation where a new symbol is created, the consequences are undefined if a subsequent attempt is made to alter that string.

Examples:

(in-package "COMMON-LISP-USER") → #<PACKAGE "COMMON-LISP-USER"> 
(intern "Never-Before") → |Never-Before|, NIL
(intern "Never-Before") → |Never-Before|, :INTERNAL
(intern "NEVER-BEFORE" "KEYWORD"):NEVER-BEFORE, NIL
(intern "NEVER-BEFORE" "KEYWORD"):NEVER-BEFORE, :EXTERNAL

See Also:

find-symbol, read, symbol, unintern, Section 2.3.4 (Symbols as Tokens)

Notes:

intern does not need to do any name conflict checking because it never creates a new symbol if there is already an accessible symbol with the name given.

Expanded Reference: intern

Basic Usage: Creating a New Symbol

intern looks up a string in a package. If no symbol with that name exists, a new one is created. It returns two values: the symbol and a status indicator.

(intern "BRAND-NEW" "COMMON-LISP-USER")
;; => BRAND-NEW
;; => NIL
;; NIL status means a new symbol was created

(intern "BRAND-NEW" "COMMON-LISP-USER")
;; => BRAND-NEW
;; => :INTERNAL
;; :INTERNAL means it was found as an internal symbol

Status Values

The second return value indicates how the symbol was found.

;; Finding an inherited symbol
(intern "CAR" "COMMON-LISP-USER")
=> CAR
=> :INHERITED

;; Finding an external symbol
(intern "CAR" "COMMON-LISP")
=> CAR
=> :EXTERNAL

;; Creating a new symbol in a fresh package
(make-package "INTERN-DEMO" :use '())
(intern "FRESH" "INTERN-DEMO")
;; => INTERN-DEMO::FRESH
;; => NIL
;; NIL means no pre-existing symbol was found

;; Looking it up again
(intern "FRESH" "INTERN-DEMO")
;; => INTERN-DEMO::FRESH
;; => :INTERNAL

Case Sensitivity

Symbol names are case-sensitive. Standard Common Lisp symbols are uppercase.

(intern "hello" "COMMON-LISP-USER")
;; => |hello|
;; => NIL
;; a new symbol with a lowercase name

(intern "HELLO" "COMMON-LISP-USER")
;; => HELLO
;; => NIL
;; a different symbol with an uppercase name

(eq (intern "hello") (intern "HELLO"))
;; => NIL

Interning into the KEYWORD Package

Symbols interned in the KEYWORD package are automatically external and self-evaluating.

(intern "MY-KEY" "KEYWORD")
;; => :MY-KEY
;; => NIL ; or :EXTERNAL if already interned

(intern "MY-KEY" "KEYWORD")
=> :MY-KEY
=> :EXTERNAL

Difference from find-symbol

Unlike find-symbol, intern creates a new symbol if one is not found.

(make-package "LOOKUP-TEST" :use '())

(find-symbol "ABSENT" "LOOKUP-TEST")
=> NIL
=> NIL

(intern "ABSENT" "LOOKUP-TEST")
;; => LOOKUP-TEST::ABSENT
;; => NIL
;; not found, so created

(find-symbol "ABSENT" "LOOKUP-TEST")
;; => LOOKUP-TEST::ABSENT
;; => :INTERNAL ; now it exists