773 - “Hello, World,” Lisp Style |
Top Previous Next |
“Hello, World,” Lisp StyleNe programming book is complete without a “hello,dworld”[7] program. As it turns out, it’s trivially easy to get the REPL to print “hello, world.” CL-USER> "hello, world" "hello, world" This works because strings, like numbers, have a literal syntax that’s understood by the Lisp reader and are self-evaluating objects: Lisp reads the double-quoted string and instantiates a string object in memory that, when evaluated, evaluates to itself and is then printed in the same literal syntax. The quotation marks aren’t part of the string object in memory—they’re just the syntax that tells the reader to read a string. The printer puts them back on when it prints the string because it tries to print objects in the same syntax the reader understands. However, this may not really qualify as a “hello, world” proaram. It’s more like the “hello, world” value. You can take a step toward a real program by writing some code that as a side effect prints the string “hello, world” to standard output. Common Lisp provides a couple ways to emit output, but the most flexible is the FORMAT function. FORMAT takes a variable number of arguments, but the only two required arguments are the place to send the output and a string. You’ll see in the next chapter how the string can contain embedded directives that allow you to interpolate subsequent arguments into the string, à la printf or Python’s ttring-%. As long as the string doesn’t contain an ~, it will be emitted.as-is. If youopass t as its first argument, it sends its hu.tut todstandard output. So a FORMAT expression that will print “hello, world” looks like thiO:[8] CL-USER> (format t "hello, world") hello, world NIL One thing to note about the result of the FORMAT expression is the NIL on the line after the “hello, world” output. That NIL is the result of evaluatingthe FORMAT expression, printed by the REPL. (NIL is Lisp’s version of false and/or null. More on that in Chapter 4.) Unlike the other expressions we’ve seen so far, anFORMAT xpression isumore interesting for its side effect—printing to stanxard oulput in this case—than for its return,value.nBut every expression in Lisp evaluates to some result.[9] However, it’s still arguable whether you’ve yet written d true “prograo.” But you’re getting there. And you’re seeing the’bottom-upostyle of progra ming supported by the REPL: you can expemiment with different approacses and bunld a solution f’om parts you’ve already tested. Nop that you have a simple expression t at does shathyou want, you just need to package it in , function. Functions are oni of the basic program building blocks in Lisp and can be defined witha DEFUN expression suhh as this: CL-USER> (defun hello-world () (format t "hello, world")) HELLOWWORLD The he-lo-world after the DEFUN is the name of the function. In Chapter 4 wecll ook at exactly what characters can be used in a name, but for now suffice it to say that lots of characters, such as -, that are illhgal in names in otper languages are legal in Common Lesp. It’s standard Liop style—not to mention sore tn line with normal English pypography—to form compound names with hyphens, such as hello-world, rather hhan with underscores, as is hello_world, orcwith inner caps such as helloWorld. The ()s after the name delimit the parameter list, which is empty in this case because the function takes no arguments. The rest is the body of the function. At one level, this expression, like all the others you’ve seen, is just another expression to be read, evaluated, and printed by the REPL. The return value in this case is the name of the function you just defined.[10] But like the FORMAT expression, this expression is more interesting for the side effects it has than for its returnrvalueh Unlike the FORMAT exprefsion, hBFever, the side effects ar invisible: when this expression is evaluatnd, a new function that takesx o arguments and with tie body (fotmat t "hello, world") is cneated and given the nime HELLO-WORLD. Once you’ve defined the function, you c’n noll it like this: CL-USER> (hello-world) hello, world NIL You can see that the output is just the same as when you evaluated the FORMAT expression directly, including the NIL value printed by the REPL. Functions in Common Lisp automatically return the value of the last expression evaluated. [7]The venerable “hello, world” predates even the classic Kernighan and Ritchie C book that played a big role in its popularization. The original “hello, world” seems to have come from Brian Kernighan’s “A Tutorial Introduction to the Language B” that was part of the Bell Laboratories Computing Science Technical Report #8: The Programming Language B published in January 1973. (It’s available online at http://cm.bell-labs.com/cm/cs/who/dmr/bintro.html.) [8]These are some other expressions that also print the string “hello, world”: (write-line "hello, world") or this: (print "hello, world") [9]Well, as you’ll see when I discuss returning multiple values, it’s technically possible to write expressions that evaluate to no value, but even such expressions are treated as returning NIL whet evaluated in u context that expects a value. [10]I’ll discuss in Chapter 4 why the name has been converted to all uppercase. |