basic-operation.lisp 18.8 KB
 Dave Cooper committed Oct 23, 2012 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ;; ;; Copyright 2002, 2009, 2012 Genworks International ;; ;; This source file is part of the General-purpose Declarative ;; Language project (GDL). ;; ;; This source file contains free software: you can redistribute it ;; and/or modify it under the terms of the GNU Affero General Public ;; License as published by the Free Software Foundation, either ;; version 3 of the License, or (at your option) any later version. ;; ;; This source file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; Affero General Public License for more details. ;; ;; You should have received a copy of the GNU Affero General Public ;; License along with this source file. If not, see ;; . ;; (in-package :gendl-doc) (defparameter *basic-operation*  Dave Cooper committed Jun 16, 2013 25 26  ((:chapter :title "Basic Operation of the GDL Environment") "This chapter will lead you through all the basic steps of  Dave Cooper committed Aug 03, 2013 27 28 29 30 31 operating a typical GDL-based development environment. We will not in this section go into particular depth about the additional features of the environment or language syntax --- this chapter is merely to familiarize you with, and start you practicing with the nuts and bolts of operating the environment with a keyboard."  Dave Cooper committed Jun 16, 2013 32 33  ((:section :title "What is Different about GDL?")  Dave Cooper committed Jun 24, 2013 34 35 36 37 38  "GDL is a " (:emph "dynamic") " language environment with incremental compiling and in-memory definitions. This means that as long as the system is running you can "  Dave Cooper committed Oct 23, 2012 39 40 41  (:emph "compile") " new " (:emph "definitions")  Dave Cooper committed Jun 16, 2013 42 43  " of functions, objects, etc, and they will immediately become available as part of the running system, and you can begin testing  Dave Cooper committed Jun 19, 2013 44 45 them immediately, or update an existing set of objects to observe their new behavior.  Dave Cooper committed Jun 16, 2013 46 47  In many other programming language systems, to introduce a new  Dave Cooper committed Jun 18, 2013 48 49 50 function or object, one has " (:emph "to start the system from the beginning") " and reload all the files in order to test new functionality.  Dave Cooper committed Oct 23, 2012 51   Dave Cooper committed Jun 18, 2013 52 53 In GDL, it is typical to keep the same development session up and running for an entire day or longer, making it unnecessary to  Dave Cooper committed Aug 03, 2013 54 repeatedly recompile and reload your definitions from scratch. Note,  Dave Cooper committed Jun 18, 2013 55 56 57 58 59 60 however, that if you do shut down and restart the system for some reason, then you will have to recompile and/or reload your application's definitions in order to bring the system back into a state where it can instantiate (or run'') your application. While this can be done manually at the command-line, it is typically  Dave Cooper committed Jun 19, 2013 61 62 63 done " (:emph "automatically") " in one of two ways:"  Dave Cooper committed Jun 18, 2013 64  (:ol  Dave Cooper committed Aug 03, 2013 65  (:li "Using commands placed into  Dave Cooper committed Jun 18, 2013 66 67 the " (:texttt "gdlinit.cl")  Dave Cooper committed Jun 24, 2013 68  " initialization file, as described in Section "  Dave Cooper committed Jun 18, 2013 69 70  (:ref "sec:customizingyourenvironment") ".")  Dave Cooper committed Aug 03, 2013 71  (:li "Alternatively, you can compile and load definitions into  Dave Cooper committed Jun 16, 2013 72 73 your session, then save the world'' in that state. That way it is possible to start a new GDL world'' which already has all your  Dave Cooper committed Oct 23, 2012 74 75 application's definitions loaded and ready for use, without having to procedurally reload any files. You can then begin to make and test new  Dave Cooper committed Jun 24, 2013 76 77 78 definitions (and re-definitions) starting from this new world.'' You can think of a saved world'' like pre-made cookie dough: no need to add each ingredient one by one --- just start making cookies!")))  Dave Cooper committed Oct 23, 2012 79 80 81  ((:section :title "Startup, Hello, World!'' and Shutdown") (:p  Dave Cooper committed Jun 24, 2013 82 83 84 85 86 87 88 89 90 91 92  "The typical GDL environment consists of three programs:" (:ol (:li "Gnu Emacs (the editor);") (:li "a Common Lisp engine with GDL system loaded or built into it (e.g. the " (:texttt "gdl.exe") " executable in your " (:texttt "program/") " directory); and") (:li "(optionally) a web browser such as Firefox, Google Chrome, Safari, Opera, or Internet Explorer")) "Emacs runs as the main "  Dave Cooper committed Oct 23, 2012 93  (:emph "process")  Dave Cooper committed Jun 16, 2013 94  ", and this in turn starts the CL engine with GDL as a "  Dave Cooper committed Oct 23, 2012 95 96 97 98  (:emph "sub-process") ". The CL engine typically runs an embedded " (:emph "webserver") ", enabling you to access your application through a standard web browser.")  Dave Cooper committed Jun 24, 2013 99  (:p "As described in Chapter "  Dave Cooper committed Oct 23, 2012 100  (:ref "chap:installation")  Dave Cooper committed Jun 16, 2013 101  ", the typical way to start a pre-packaged GDL environment is with the "  Dave Cooper committed Oct 23, 2012 102 103 104  (:texttt "run-gdl.bat") " (Windows), or " (:texttt "run-gdl")  Dave Cooper committed Jun 16, 2013 105 106 107  " (MacOS, Linux) script files, or with the installed Start program item (Windows) or application bundle (MacOS). Invoke this script file from the Start menu (Windows), your computer's file  Dave Cooper committed Jun 18, 2013 108 109 110 manager, or from a desktop shortcut if you have created one. Your installation executable may also have created a Windows Start'' menu item for Genworks GDL. You can of course also invoke "  Dave Cooper committed Oct 23, 2012 111 112 113 114 115 116  (:texttt "run-gdl.bat") " from the Windows cmd'' command-line, or from another command shell such as Cygwin." (:footnote "Cygwin is also useful as a command-line tool on Windows for interacting with a version control system like Subversion (svn)."))  Dave Cooper committed Jun 18, 2013 117 118 119 120 121  ((:image-figure :caption "Startup of Emacs with GDL" :image-file "emacs-startup.png" :width "6in" :height "4in" :label "fig:emacs-startup"))  Dave Cooper committed Oct 23, 2012 122  ((:subsection :title "Startup")  Dave Cooper committed Jun 16, 2013 123  " Startup of a typical GDL development session consists of  Dave Cooper committed Oct 23, 2012 124 two fundamental steps: (1) starting the Emacs editing environment,  Dave Cooper committed Jun 16, 2013 125 126 127 and (2) starting the actual GDL process as a sub-process'' or inferior'' process within Emacs. The GDL process should automatically establish a network connection back to Emacs, allowing you to interact directly with the GDL process from within Emacs."  Dave Cooper committed Oct 23, 2012 128  ((:list :style :enumerate)  Dave Cooper committed Jun 16, 2013 129 130 131 132  (:item "Invoke the " (:texttt "run-gdl.bat") ", " (:texttt "run-gdl.bat") " startup script, or the provided executable from the Start menu (windows) or application bundle (Mac).")  Dave Cooper committed Jun 18, 2013 133  (:item "You should see an emacs window similar to that shown in Figure "  Dave Cooper committed Oct 23, 2012 134 135  (:ref "fig:emacs-startup") ". (alternative colors are also possible).")  Dave Cooper committed Jun 16, 2013 136 137  (:item "(MS Windows): Look for the Genworks GDL Console  Dave Cooper committed Oct 23, 2012 138 window, or (Linux, Mac) use the Emacs Buffer'' menu to visit the  Dave Cooper committed Jun 16, 2013 139 *inferior-lisp*'' buffer. Note that the Genworks GDL Console  Dave Cooper committed Oct 23, 2012 140 141 142 143 window might start as a minimized icon; click or double-click it to un-minimize.") (:item "Watch the Genworks GDL Console window for any errors. Depending on your specific installation, it may take from a  Dave Cooper committed Jun 16, 2013 144 few seconds to several minutes for the Genworks GDL Console (or  Dave Cooper committed Oct 23, 2012 145 146 147 148 149 150 *inferior-lisp* buffer) to settle down and give you a " (:texttt "gdl-user(): ") " prompt. This window is where you will see most of your program's textual output, any error messages, warnings, etc.") (:item "In Emacs, type: "  Dave Cooper committed Apr 16, 2014 151  (:texttt "C-x &")  Dave Cooper committed Oct 23, 2012 152 153 154  " (or select Emacs menu item " "Buffers$\\rightarrow$*slime-repl...*" ") to visit the *slime-repl ...*'' buffer. The full name  Dave Cooper committed Jun 16, 2013 155 of this buffer depends on the specific CL/GDL platform which you are  Dave Cooper committed Oct 23, 2012 156 157 running. This buffer contains an interactive prompt, labeled " (:texttt "gdl-user>")  Dave Cooper committed Jun 16, 2013 158  ", where you will enter most of your commands to interact with your running GDL session  Dave Cooper committed Oct 23, 2012 159 160 for testing, debugging, etc. There is also a web-based graphical interactive environment called " (:emph "tasty")  Dave Cooper committed Jun 16, 2013 161  " which will be discussed in Chapter "  Dave Cooper committed Jun 18, 2013 162  (:ref "chap:thetastydevelopmentenvironment") ".")  Dave Cooper committed Oct 23, 2012 163   Dave Cooper committed Jun 16, 2013 164  (:item "To ensure that the GDL command prompt is up and running, type: "  Dave Cooper committed Oct 23, 2012 165 166 167 168 169 170  (:texttt "(+ 2 3)") " and press [Enter].") (:item "You should see the result " (:texttt "5") " echoed back to you below the prompt.")))  Dave Cooper committed Jun 16, 2013 171  ((:subsection :title "Developing and Testing a Hello World'' application")  Dave Cooper committed Oct 23, 2012 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194  " " ((:list :style :enumerate) (:item "type C-x (Control-x) 2, or C-x 3, or use the Split Screen'' option of the File menu to split the Emacs frame into two windows'' (windows'' in Emacs are non-overlapping panels, or rectangular areas within the main Emacs window).") (:item "type C-x o several times to move from one window to the other, or move the mouse cursor and click in each window. Notice how the blinking insertion point moves from one window to the other.") (:item "In the top (or left) window, type C-x C-f (or select Emacs menu item File$\\rightarrow$Open File'') to get the Find file'' prompt in the mini-buffer.") (:item "Type C-a to move the point to the beginning of the mini-buffer line.") (:item "Type C-k to delete from the point to the end of the mini-buffer.") (:item "Type " (:texttt "\\textasciitilde/hello.gdl") " and press [Enter]")  Dave Cooper committed Jun 16, 2013 195  (:item "You are now editing a (presumably new) file of GDL  Dave Cooper committed Oct 23, 2012 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227  code, located in your HOME directory, called " (:texttt "hello.gdl")) (:item "Enter the text from Figure " (:ref "fig:simpleobjectdefinition") " into the " (:texttt "hello.gdl") " buffer. You do not have to match the line breaks and whitespace as shown in the example. You can auto-indent each new line by pressing [TAB] after pressing [Enter] for the newline." (:p (:emph "Protip:") "You can also try using " (:texttt "C-j") " instead of [Enter], which will automatically give a newline and auto-indent.")) ((:boxed-figure :caption "Example of Simple Object Definition" :label "fig:simpleobjectdefinition") (:verbatim " (in-package :gdl-user) (define-object hello () :computed-slots ((greeting \"Hello, World!\"))) ")) (:item "type " (:texttt "C-x C-s") " (or choose Emacs menu item " (:emph "File$\\rightarrow$Save") ") to save the contents of the buffer (i.e. the window) to the file in your HOME directory.") (:item "type " (:texttt "C-c C-k") " (or choose Emacs menu item " (:emph "SLIME$\\rightarrow$Compilation$\\rightarrow$Compile/Load File")  Dave Cooper committed Apr 16, 2014 228  ") to compile & load the code from this file.")  Dave Cooper committed Oct 23, 2012 229 230 231  (:item "type " (:texttt "C-c o") " (or move and click the mouse) to switch to the bottom window.")  Dave Cooper committed Apr 16, 2014 232  (:item "In the bottom window, type " (:texttt "C-x &") " (or choose Emacs menu item "  Dave Cooper committed Oct 23, 2012 233 234 235 236  (:emph "Buffers$\\rightarrow$*slime-repl...*") ") to get the " (:texttt "*slime-repl ...*") " buffer, which should contain a " (:texttt "gdl-user>")  Dave Cooper committed Jun 16, 2013 237  " prompt. This is where you normally type interactive GDL commands.")  Dave Cooper committed Oct 23, 2012 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261  (:item "If necessary, type " (:texttt "M \\textgreater") " (that is, hold down Meta (Alt), Shift, and the \\textgreater'' key) to move the insertion point to the end of this buffer.") (:item "At the " (:texttt "gdl-user>") " prompt, type " (:verbatim "(make-self 'hello)") " and press [Enter].") (:item "At the " (:texttt "gdl-user>") " prompt, type " (:verbatim "(the greeting)") " and press [Enter].") (:item "You should see the words " (:texttt "Hello, World!") " echoed back to you below the prompt.") )) ((:subsection :title "Shutdown")  Dave Cooper committed Jun 16, 2013 262  " To shut down a development session gracefully, you should first shut down the GDL process,  Dave Cooper committed Oct 23, 2012 263 264 265 then shut down your Emacs." ((:list :style :itemize) (:item "Type "  Dave Cooper committed Jun 16, 2013 266  (:texttt "M-x quit-gdl")  Dave Cooper committed Oct 23, 2012 267  " (that is, hold Alt and press X, then release both while you type "  Dave Cooper committed Jun 16, 2013 268  (:texttt "quit-gdl")  Dave Cooper committed Oct 23, 2012 269 270  " in the mini-buffer), then press [Enter]")  Dave Cooper committed Jun 16, 2013 271  (:item "alternatively, you can type "  Dave Cooper committed Apr 16, 2014 272 273  (:texttt "C-x &") " (that is, hold Control and press X, then release both while you type &.  Dave Cooper committed Jun 16, 2013 274 This will visit the *slime-repl* buffer. Now type: "  Dave Cooper committed Jun 18, 2013 275  (:texttt ", q")  Dave Cooper committed Jun 16, 2013 276 277 278  " to quit the GDL session.") (:item "Finally, type "  Dave Cooper committed Oct 23, 2012 279  (:texttt "C-x C-c")  Dave Cooper committed Jun 16, 2013 280 281  " to quit from Emacs. Emacs will prompt you to save any modified buffers before exiting."))))  Dave Cooper committed Oct 23, 2012 282 283  ((:section :title "Working with Projects")  Dave Cooper committed Jun 18, 2013 284  "GDL contains utilities which allow you to treat your  Dave Cooper committed Oct 23, 2012 285 286 application as a project,'' with the ability to compile, incrementally compile, and load a project'' from a directory tree of  Dave Cooper committed Aug 03, 2013 287 source files representing your project. In this section we provide an  Dave Cooper committed Oct 23, 2012 288 289 290 291 overview of the expected directory structure and available control files, followed by a reference for each of the functions included in the bootstrap module." ((:subsection :title "Directory Structure")  Dave Cooper committed Oct 26, 2012 292 293 294   Dave Cooper committed Jun 24, 2013 295 296 297 298 299  (:p "You should structure your applications in a modular fashion, with the directories containing actual Lisp sources called \"source.\" You may have subdirectories which themselves contain \"source\" directories. We recommend keeping your codebase directories relatively flat, however.")  Dave Cooper committed Oct 23, 2012 300 301 302  (:p "In Figure " (:ref "fig:yoyodyne-base")  Dave Cooper committed Oct 26, 2012 303 304 305 306 307 308 309 310 311  " is an example application directory, with four source files.") ((:boxed-figure :caption "Example project directory with four source files" :label "fig:yoyodyne-base") (:verbatim " apps/yoyodyne/booster-rocket/source/assembly.gdl apps/yoyodyne/booster-rocket/source/package.gdl apps/yoyodyne/booster-rocket/source/parameters.gdl apps/yoyodyne/booster-rocket/source/rules.gdl  Dave Cooper committed Aug 03, 2013 312 ")))  Dave Cooper committed Oct 26, 2012 313 314 315 316 317 318 319 320  ((:subsection :title "Source Files within a source/ subdirectory") ((:subsubsection :title "Enforcing Ordering") (:p "Within a source subdirectory, you may have a file called " (:texttt "file-ordering.isc") (:footnote (:texttt "isc") " stands for Intelligent Source Configuration''")  Dave Cooper committed Aug 03, 2013 321  " to enforce a certain ordering of the files. Here are  Dave Cooper committed Jun 24, 2013 322 the contents of an example for the above application:")  Dave Cooper committed Jun 16, 2013 323  (:verbatim "(\"package\" \"parameters\")")  Dave Cooper committed Oct 26, 2012 324 325 326 327 328 329 330  (:p "This will force package.lisp to be compiled/loaded first, and parameters.lisp to be compiled/loaded next. The ordering on the rest of the files should not matter (although it will default to lexigraphical ordering).")  Dave Cooper committed Aug 03, 2013 331 332  (:p "Now our sample application directory appears as in Figure "  Dave Cooper committed Oct 26, 2012 333  (:ref "fig:yoyodyne-with-file-ordering-isc")  Dave Cooper committed Jun 16, 2013 334  "."))  Dave Cooper committed Oct 26, 2012 335 336 337 338 339 340 341 342 343  ((:boxed-figure :caption "Example project directory with file ordering configuration file" :label "fig:yoyodyne-with-file-ordering-isc") (:verbatim " apps/yoyodyne/booster-rocket/source/assembly.gdl apps/yoyodyne/booster-rocket/source/file-ordering.isc apps/yoyodyne/booster-rocket/source/package.gdl apps/yoyodyne/booster-rocket/source/parameters.gdl apps/yoyodyne/booster-rocket/source/rules.gdl"))  Dave Cooper committed Nov 19, 2012 344   Dave Cooper committed Oct 26, 2012 345   Dave Cooper committed Nov 19, 2012 346  )  Dave Cooper committed Oct 26, 2012 347 348   Dave Cooper committed Nov 19, 2012 349 350 351  ((:subsection :title "Generating an ASDF System") (:p "ASDF stands for Another System Definition Facility, which is the predominant system in use for Common Lisp third-party  Dave Cooper committed Jun 18, 2013 352  libraries. With GDL, you can use the "  Dave Cooper committed Nov 19, 2012 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377  (:texttt ":create-asd-file?") " keyword argument to make cl-lite generate an ASDF system file instead of actually compiling and loading the system. For example: " (:verbatim "(cl-lite \"apps/yoyodyne/\" :create-asd-file? t)")) (:p "In order to include a depends-on clause in your ASDF system file, create a file called " (:texttt "depends-on.isc") " in the toplevel directory of your system. In this file, place a list of the systems your system depends on. This can be systems from your own local projects, or from third-party libraries. For example, if your system depends on the " (:texttt ":cl-json") " third-party library, you would have the following contents in your " (:texttt "depends-on.isc") ": " (:verbatim "(:cl-json)"))) ((:subsection :title "Compiling and Loading a System") "Once you have generated an ASDF file, you can compile and load the system using Quicklisp. To do this for our example, follow these steps:" ((:list :style :enumerate) (:item (:verbatim "(cl-lite \"apps/yoyodyne/\" :create-asd-file? t)") " to generate the asdf file for the yoyodyne system. This only has to be done once after every time you add, remove, or rename a file or folder from the system.")  Dave Cooper committed Oct 23, 2014 378  (:item (:verbatim "(pushnew \"apps/yoyodyne/\" ql:*local-project-directories* :test #'equalp)")  Dave Cooper committed Nov 19, 2012 379 380 381 382 383  " This can be done in your " (:texttt "gdlinit.cl") " for projects you want available during every development session. Note that you should include the full path prefix for the directory containing the ASDF system file.") (:item (:verbatim "(ql:quickload :gdl-yoyodyne)")  Dave Cooper committed Aug 03, 2013 384  " This will compile and load the actual system. Quicklisp  Dave Cooper committed Jun 16, 2013 385 386 387 388 389 uses ASDF at the low level to compile and load the systems, and Quicklisp will retrieve any depended-upon third-party libraries from the Internet on-demand. Source files will be compiled only if the corresponding binary (fasl) file does not exist or is older than the source file. By default, ASDF keeps its binary files in a "  Dave Cooper committed Nov 19, 2012 390  (:emph "cache")  Dave Cooper committed Aug 03, 2013 391  " directory, separated according to the CL platform and  Dave Cooper committed Jun 16, 2013 392 393 394 operating system. The location of this cache is system-dependent, but you can see where it is by observing the compile and load process."))))  Dave Cooper committed Nov 19, 2012 395   Dave Cooper committed Oct 23, 2012 396 397 398  ((:section :title "Customizing your Environment") " You may customize your environment in several different ways,  Dave Cooper committed Jun 18, 2013 399 for example by loading definitions and settings into your GDL  Dave Cooper committed Oct 23, 2012 400 401 402 403 404 405 406 407 world'' automatically when the system starts, and by specifying fonts, colors, and default buffers (to name a few) for your emacs editing environment." ) ((:section :title "Saving the World")  Dave Cooper committed Jun 18, 2013 408 409  "Saving the world'' refers to a technique of saving a complete binary image of your GDL world'' which contains all the currently  Dave Cooper committed Nov 19, 2012 410 compiled and loaded definitions and settings. This allows you to  Dave Cooper committed Jun 16, 2013 411 412 413 414 start up a saved world almost instantly, without being required to reload all the definitions. You can then incrementally compile and load just the particular definitions which you are working on for your development session.  Dave Cooper committed Nov 19, 2012 415   Dave Cooper committed Nov 19, 2012 416 To save a world, follow these steps:"  Dave Cooper committed Nov 19, 2012 417   Dave Cooper committed Nov 19, 2012 418  ((:list :style :enumerate)  Dave Cooper committed Jun 18, 2013 419  (:item "Load the base GDL code and (optionally) code for GDL  Dave Cooper committed Oct 23, 2014 420 421 422 423 424 modules (e.g. gdl-yadd, gdl-tasty) you want to be in your saved image. Note that in some implementations, this has step to be done in a plain session without multiprocessing (i.e. without an Emacs connection) - so you would do this loading step from a command shell e.g. Windows cmd prompt. For example:"  Dave Cooper committed Nov 19, 2012 425 426 427 428  (:verbatim " (ql:quickload :gdl-yadd) (ql:quickload :gdl-tasty)"))  Dave Cooper committed Oct 23, 2014 429 430 431  (:item "(needed only for full GDL):" (:verbatim "(ff:unload-foreign-library (merge-pathnames \"smlib.dll\" \"sys:smlib;\"))")) (:item (:verbatim "(net.aserve:shutdown)"))  Dave Cooper committed Nov 19, 2012 432 433  (:item " (to save an image named yoyodyne.dxl) Invoke the command "  Dave Cooper committed Oct 23, 2014 434 435  (:verbatim "(ensure-directories-exist \"~/gdl-images/\")") (:verbatim "(uiop:dump-image dumplisp \"~/gdl-images/yoyodyne\")")  Dave Cooper committed Nov 19, 2012 436 437 438 439 440 441  "Note that the standard extension for Allegro CL images is " (:texttt ".dxl") ". Prepend the file name with path information, to write the image to a specific location."))) ((:section :title "Starting up a Saved World")  Dave Cooper committed Jun 18, 2013 442  "In order to start up GDL using a custom saved image, or world,'' follow these steps"  Dave Cooper committed Nov 19, 2012 443  ((:list :style :enumerate)  Dave Cooper committed Jun 18, 2013 444  (:item "Exit GDL")  Dave Cooper committed Oct 23, 2014 445  (:item "Copy the supplied image file, e.g."  Dave Cooper committed Nov 19, 2012 446 447 448 449 450 451  (:texttt "gdl.dxl") " to " (:texttt "gdl-orig.dxl") ".") (:item "Move the custom saved dxl image to " (:texttt "gdl.dxl")  Dave Cooper committed Jun 18, 2013 452  " in the GDL application "  Dave Cooper committed Dec 13, 2012 453  (:texttt "\"program/\"")  Dave Cooper committed Nov 19, 2012 454  " directory.")  Dave Cooper committed Jun 18, 2013 455  (:item "Start GDL as usual. Note: you may have to edit the system gdlinit.cl or your home gdlinit.cl  Dave Cooper committed Nov 19, 2012 456 to stop it from loading redundant code which is already in the saved image.")))))  Dave Cooper committed Oct 23, 2012 457 458 459 460 461 462 463 464  `