Szukaj…


Uwagi

Jest to prosta funkcja Witaj świecie w Common Lisp. Przykłady wydrukują tekst Hello, World! (bez cudzysłowu; po nim nowy wiersz) na standardowe wyjście.

Common Lisp to język programowania, który jest w dużej mierze wykorzystywany interaktywnie przy użyciu interfejsu znanego jako REPL. REPL (Read Eval Print Loop) pozwala wpisać kod, poddać go ocenie (uruchomić) i natychmiast zobaczyć wyniki. Monit o REPL (w którym momencie należy wpisać kod do uruchomienia) jest oznaczony przez CL-USER> . Czasami przed > pojawi się coś innego niż CL-USER , ale nadal jest to REPL.

Po pytaniu pojawia się kod, zwykle albo pojedyncze słowo (tj. Nazwa zmiennej), albo formularz (lista słów / formularzy zamkniętych między ( i ) ) (tj. Wywołanie funkcji lub deklaracja itp.). W następnym wierszu będzie każde wyjście, które program wypisuje (lub nic, jeśli program nic nie wypisuje), a następnie wartości zwracane przez ocenę wyrażenia. Zwykle wyrażenie zwraca jedną wartość, ale jeśli zwraca wiele wartości, pojawiają się raz na linię.

Wersje

Wersja Data wydania
Common Lisp 1984-01-01
ANSI Common Lisp 01.01.1994

Witaj świecie

Poniżej znajduje się fragment sesji REPL z Common Lisp, w której „Witaj, świecie!” funkcja jest zdefiniowana i wykonana. Zobacz uwagi na dole tej strony, aby uzyskać dokładniejszy opis REPL.

CL-USER> (defun hello ()
           (format t "Hello, World!~%"))
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> 

Definiuje to „funkcję” zerowych argumentów o nazwie hello , która zapisze ciąg "Hello, World!" po którym następuje nowa linia na standardowe wyjście i zwraca NIL .

Aby zdefiniować funkcję, piszemy

(defun name (parameters...)
  code...)

W tym przypadku funkcja nazywa się hello , nie przyjmuje parametrów, a uruchamiany przez nią kod wykonuje jedno wywołanie funkcji. Zwrócona wartość z funkcji lisp jest ostatnim bitem kodu w funkcji do uruchomienia, więc hello zwraca cokolwiek (format t "Hello, World!~%") Zwraca.

W lisp do wywołania funkcji zapisuje się (function-name arguments...) gdzie function-name to nazwa funkcji, a arguments... to (oddzielona spacjami) lista argumentów wywołania. Istnieją specjalne przypadki, które wyglądają jak wywołania funkcji, ale na przykład w powyższym kodzie nie ma wywoływanej funkcji defun , jest ona traktowana specjalnie i zamiast niej definiuje funkcję.

W drugim monicie REPL, po zdefiniowaniu funkcji hello , wywołujemy ją bez parametrów, pisząc (hello) . To z kolei wywoła funkcję format z parametrami t "Hello, World!~%" . format funkcja produkuje wyjście sformatowaną w oparciu o argumenty, które jest przekazywana (trochę jak zaawansowana wersja printf w C). Pierwszy argument mówi mu, do którego wyjścia, t oznacza standardowe wyjście. Drugi argument mówi mu, co wydrukować (i jak interpretować dodatkowe parametry). Dyrektywa (specjalny kod w drugim argumencie) ~% mówi formatowi, aby wypisał nowy wiersz (tzn. W UNIX może napisać \n a w Windows \r\n ). Format zwykle zwraca NIL (trochę jak NULL w innych językach).

Po drugim pytaniu widzimy, że Hello, World został wydrukowany, aw następnym wierszu zwrócona wartość to NIL .

Cześć, imię

Jest to nieco bardziej zaawansowany przykład, który pokazuje kilka dodatkowych cech wspólnego seplenienia. Zaczynamy od prostego Hello, World! funkcjonować i zademonstrować interaktywny rozwój na REPL. Zauważ, że dowolny tekst z średnika ; , do końca linii jest komentarz.

CL-USER> (defun hello ()
       (format t "Hello, World!~%")) ;We start as before
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (defun hello-name (name) ;A function to say hello to anyone
       (format t "Hello, ~a~%" name)) ;~a prints the next argument to format
HELLO-NAME
CL-USER> (hello-name "Jack")
Hello, Jack
NIL
CL-USER> (hello-name "jack") ;doesn't capitalise names
Hello, jack
NIL
CL-USER> (defun hello-name (name) ;format has a feature to convert to title case
       (format t "Hello, ~:(~a~)~%" name)) ;anything between ~:( and ~) gets it
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack")
Hello, Jack
NIL
CL-USER> (defun hello-name (name)
       (format t "Hello, ~:(~a~)!~%" name))
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack") ;now this works
Hello, Jack!
NIL
CL-USER> (defun hello (&optional (name "world")) ;we can take an optional argument
       (hello-name name)) ;name defaults to "world"
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (hello "jack")
Hello, Jack!
NIL
CL-USER> (hello "john doe") ;note that this capitalises both names
Hello, John Doe!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~a ~r" name number)) ;~r prints a number in English
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;this doesn't quite work
Hello, Louis sixteen
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~:r~)!" name number)) ;~:r prints an ordinal
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Sixteenth!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~@r~)!" name number)) ;~@r prints Roman numerals
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Xvi!
NIL
CL-USER> (defun hello-person (name &key (number)) ;capitalisation was wrong
       (format t "Hello, ~:(~a~) ~:@r!" name number))
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;thats better
Hello, Louis XVI!
NIL
CL-USER> (hello-person "Louis") ;we get an error because NIL is not a number
Hello, Louis ; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {1006641AB3}>.
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 "")) ; here we define a variable called number
         (title (if title 
                (format nil "~:(~a~) " title)
                ""))) ; and here one called title
         (format nil "~a~:(~a~)~a" title name number))) ;we use them here

SAY-PERSON
CL-USER> (say-person "John") ;some examples
"John"
CL-USER> (say-person "john doe")
"John Doe"
CL-USER> (say-person "john doe" :number "JR")
"John Doe Jr"
CL-USER> (say-person "john doe" :number "Junior")
"John Doe Junior"
CL-USER> (say-person "john doe" :number 1)
"John Doe I"
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;this is wrong
"John Doe First"
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " the ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 ""))
         (title (if title 
                (format nil "~:(~a~) " title)
                "")))
         (format nil "~a~:(~a~)~a" title name number)))
WARNING: redefining COMMON-LISP-USER::SAY-PERSON in DEFUN
SAY-PERSON
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;thats better
"John Doe the First"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number nil)
"King Louis the Sixteenth"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number t)
"King Louis XVI"
CL-USER> (defun hello (&optional (name "World") &rest arguments) ;now we will just
       (apply #'hello-name name arguments)) ;pass all arguments to hello-name
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (defun hello-name (name &rest arguments) ;which will now just use
       (format t "Hello, ~a!" (apply #'say-person name arguments))) ;say-person
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello "louis" :title "king" :number 16) ;this works now
Hello, King Louis XVI!
NIL
CL-USER>

Podkreśla to niektóre zaawansowane funkcje funkcji format Common Lisp, a także niektóre funkcje, takie jak parametry opcjonalne i argumenty słów kluczowych (np . :number ). Daje to również przykład interaktywnego rozwoju na REPL we wspólnym seplenieniu.

Prosty program Hello World w REPL

Common Lisp REPL to środowisko interaktywne. Każdy formularz napisany po pytaniu jest oceniany, a jego wartość jest następnie drukowana w wyniku oceny. Więc najprostsze możliwe „Witaj, świecie!” program w Common Lisp to:

CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>

To, co się tutaj dzieje, polega na tym, że łańcuch wejściowy jest podawany do REPL, jest analizowany, a wynik jest drukowany. Z tego przykładu widać, że ciągi znaków, takie jak liczby, specjalne symbole, takie jak NIL i T oraz kilka innych literałów, są formami samooceny : to znaczy oceniają je same.

Podstawowe wyrażenia

Wypróbujmy podstawowe wyrażenie w REPL:

CL-USER> (+ 1 2 3)
6
CL-USER> (- 3 1 1)
1
CL-USER> (- 3)
-3
CL-USER> (+ 5.3 (- 3 2) (* 2 2))
10.3
CL-USER> (concatenate 'string "Hello, " "World!")
"Hello, World!"
CL-USER> 

Podstawowym elementem składowym programu Common Lisp jest forma . W tych przykładach mamy formularze funkcji , czyli wyrażenia zapisane jako lista, w których pierwszym elementem jest operator (lub funkcja), a pozostałe elementy to operandy (to się nazywa „Notacja przedrostka” lub „Notacja polska” ”). Pisanie formularzy w REPL powoduje ich ocenę. W przykładach można zobaczyć proste wyrażenia, których argumentami są stałe liczby, ciągi znaków i symbole (w przypadku 'string , który jest nazwą typu). Widać również, że operatory arytmetyczne mogą przyjmować dowolną liczbę argumentów.

Należy zauważyć, że nawiasy są integralną częścią składni i nie mogą być używane swobodnie, jak w innych językach programowania. Na przykład następujący błąd:

(+ 5 ((+ 2 4)))
> Error: Car of ((+ 2 4)) is not a function name or lambda-expression. ...

We wspólnych formularzach Lisp mogą być również dane, symbole, formularze makro, formularze specjalne i formularze lambda. Mogą być zapisywane do oceny, zwracając zero, jedną lub więcej wartości, lub mogą być podawane w danych wejściowych do makra, które przekształcają je w inne formy.

Suma listy liczb całkowitych

(defun sum-list-integers (list)
    (reduce '+ list))

; 10
(sum-list-integers '(1 2 3 4))

; 55
(sum-list-integers '(1 2 3 4 5 6 7 8 9 10))

Wyrażenia lambda i funkcje anonimowe

Anonimową funkcję można zdefiniować bez nazwy poprzez wyrażenie lambda . Do zdefiniowania tego typu funkcji używa się słowa kluczowego lambda zamiast słowa kluczowego defun . Wszystkie poniższe wiersze są równoważne i definiują anonimowe funkcje, które generują sumę dwóch liczb:

(lambda (x y) (+ x y))
(function (lambda (x y) (+ x y)))
#'(lambda (x y) (+ x y))

Ich użyteczność jest zauważalna przy tworzeniu formularzy Lambda , tj. Formularzy, które są listą, w której pierwszym elementem jest wyrażenie lambda, a pozostałe elementy to argumenty funkcji anonimowej. Przykłady ( wykonanie online ):

(print ((lambda (x y) (+ x y)) 1 2)) ; >> 3

(print (mapcar (lambda (x y) (+ x y)) '(1 2 3) '(2 -5 0))) ; >> (3 -3 3)

Wspólne zasoby edukacyjne Lisp

Książki online

Są to książki ogólnodostępne online.

Referencje online

Książki offline

Są to książki, które prawdopodobnie będziesz musiał kupić lub wypożyczyć w bibliotece.

Społeczności internetowe

Biblioteki

  • Quicklisp jest menedżerem bibliotek dla Common Lisp i ma długą listę obsługiwanych bibliotek .
  • Quickdocs obsługuje dokumentację bibliotek dla wielu bibliotek CL.
  • Awesome CL to kierowana przez społeczność wyselekcjonowana lista bibliotek, ram i innych lśniących rzeczy posortowanych według kategorii.

Wstępnie zapakowane środowiska Lisp

Są to środowiska edycyjne Lisp, które są łatwe do zainstalowania i rozpoczęcia, ponieważ wszystko, czego potrzebujesz, jest wstępnie spakowane i wstępnie skonfigurowane.

  • Portacle to przenośne i wieloplatformowe środowisko Common Lisp. Dostarcza nieco spersonalizowanych Emacsa ze Slime, SBCL (popularną implementacją Common Lisp), Quicklisp i Git. Nie wymaga instalacji, więc jest to bardzo szybki i łatwy sposób na rozpoczęcie pracy.
  • Lispbox to IDE (Emacs + SLIME), środowisko Common Lisp (Clozure Common Lisp) i menedżer bibliotek (Quicklisp), wstępnie spakowane jako archiwa dla systemów Windows, Mac OSX i Linux. Potomek „Lisp in a Box” zalecany w książce Practical Common Lisp.
  • Nie jest fabrycznie zapakowany, ale SLIME zmienia Emacsa w Common Lisp IDE i ma instrukcję obsługi, która pomoże ci zacząć. Wymaga osobnej implementacji Common Lisp.

Typowe implementacje Lisp

W tej sekcji wymieniono niektóre typowe implementacje języka CL i ich instrukcje. O ile nie zaznaczono inaczej, są to implementacje wolnego oprogramowania. Zobacz także listę darmowego oprogramowania Common Lisp Implementacje Cliki oraz listę komercyjnych komercyjnych implementacji Common Lisp .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow