6 ms·
I'm used to languages like Python, that have a number of files that are modules, and to start a program you run one of them as an entry point. C programs consi
by Scarblac 10y ago
I'm used to languages like Python, that have a number of files that are modules, and to start a program you run one of them as an entry point.
C programs consist of a lot of files that are compiled and linked into a binary executable.
Whenever I've tried to learn CL, I couldn't really wrap my head around what the eventual program would be. You build an in-memory state by adding things to it, later dump it to a binary. How do you get an overview of what there is?
I'm just too used to my files, perhaps. Or I'm missing something.
- reikonomusha 10y agoLisp offers a lot of ways to check what there is. You can inspect, search, look at source code, docs, assembly code. All of these things are dynamically inspectable. Tools like Emacs and SLIME make it easier. You can still look at the files that get loaded. Lisp organizes itself around systems (libraries) and packages (namespaces). It's good to check what packages a system has, then you can check out the symbols provided by a package. Lisp isn't totally wild-west in the concept of the Lisp image. There is organization to good code.
- jlarocco 10y agoI don't know where you got that impression, but CL development is no different than Python development. Code goes in .lisp files, and then you either load it into the REPL or pass it to the compiler and tell it what the entry point is. I suppose it's technically possible to develop an entire application at the REPL and then dump to a binary, but I don't think anybody does that any more than they do it in Python.
- chaoky 10y agoIn Common Lisp, you write to source code files and then use ASDF/Quicklisp to compile/load that project. If you feel the need to create a standalone executable you can dump the image with an entry function specified. It's essentially the same as python, although standalone executable are less prominent than in-image programming.
- quickoats 10y agoLisp is quite abstract, let us say more so than C, where we can visualize the pointers and memory chunks and operators fairly accurately while programming. Lisp is more symbolic and ethereal; like the ocean full of its interlocking organic forms. One would wonder what lies below the surface upon merely apprehending the calmly undulating surface...
- lispm 10y agoCommon Lisp implementations do whatever you want. > I'm used to languages like Python, that have a number of files that are modules, and to start a program you run one of them as an entry point. You can do that. start a Lisp with a file to load at start, it can then load the dependencies. > C programs consist of a lot of files that are compiled and linked into a binary executable. You can do that, too. That's typical when you create a 'system' declaration which describes your software. ASDF would be a tool for that. You then compile the software, load it and dump an image. Some implementations have a more elaborate way to create applications or can create loadable libraries, which you can integrate into other applications. > You build an in-memory state by adding things to it, later dump it to a binary. How do you get an overview of what there is? Typically you would work with files. Write the code in files, evaluate the code from there and build the software from time to time as a whole. If you use SBCL, then you get tons of compile time information, type checks, efficiency hints, warnings, ....
- brudgers 10y agoI mentioned elsewhere I'm learning Common Lisp. I'm also learning Python by translating some Common Lisp code into Python and part of that is to make sure I understand what the Common Lisp is doing. As an understatement, that's meant building some very unPythonic abstractions (yay, me). Anyway, I think there is a fundamental design difference between Common Lisp and other 'first class' programming languages: Common Lisp was designed as a way to use computers because a computer user would sit down at a Lisp Machine (which was the future when Common Lisp was designed) and use Common Lisp to do ordinary computer stuff like store their recipes and manage appointments and copy files between directories. It's reflected in the :cl-user package not being called :cl-programmer and the logic of typing (in-package :tps-report) on Saturday at the usual time. Most other languages don't have this idea...In Unix users don't fool around with stdio.h. In Python, there's no clean way of switching between applications at the REPL -- or rather interpreter -- because of how Python handles the hard job of naming things (like most languages, there's a bit of punting on third down with the catchall epithet 'unpythonic'). This makes it hard to get one's head around Common Lisp, but it explains why a person might leave a REPL running for a week and make better progress because of it.
- lispm 10y ago> Lisp Machine (which was the future when Common Lisp was designed) Common Lisp was actually designed so that you don't need a Lisp Machine. The people working on it were from CMU (Unix workstations), Lucid (Unix workstations), Franz (Unix/Windows), Apple (Mac), Symbolics (Lispm, PC), Xerox (Lispm, Unix), and many others. Users used an editor-based IDE (like Franz ELI with GNU Emacs, ILISP with Gnu Emacs), a special IDE usually written in Lisp (Franz, LispWorks, Macintosh Common Lisp, Golden CL on Windows, ...) or even a Lisp Machine which combines the IDE with the operating system. > copy files between directories The Symbolics Lisp Listener (REPL + commands) has a command language/interface with a lot of comfort - but with its own usability problems. You would often type Copy File *.lisp.newest >subdir> instead of using the Lisp function COPY-FILE. Still today I tend to keep the Lisp IDE running for days/weeks/months... as long as possible. Sometimes Linux tells me I have to restart the machine after some software update...
- 10y ago
- rayiner 10y agoIn a compiled system like SBCL, things work much as they do in C, except the process is more "programmable." To recap: when you load a (dynamically-linked) C program in Linux or OS X, the OS will create a new process, and map the dynamic linker (ld-linux.so or dyld) into that process's memory. It then transfers control to the dynamic linker. The dynamic linker then loads the rest of the program into memory (from ".so" or ".dylib" or ".dll" files) and links everything together (i.e. resolves symbol addresses) before passing control to the application entry point. A compiled Lisp system like SBCL works much the same way, except it uses its own linking/compilation machinery. A new process is bootstrapped by running a C program, which loads the Lisp image into memory. The image is compiled code/data containing the Lisp runtime, compiler, and standard library. After the Lisp image is loaded, you've got two things to work with: COMPILE and LOAD. COMPILE takes Lisp source code and compiles it into a FASL (compiled code and data, equivalent to a ".o" file). LOAD functions much like dyld or ld-linux, and loads compiled code and data into the running process. Indeed, in some implementations like ECL, LOAD is just built on dlopen(). The "eventual program" is ultimately built by LOAD-ing the FASL files comprising the program. In practice, you don't do this manually. Instead, you use something like ASDF: https://common-lisp.net/project/asdf/asdf.html#Defining-systems-with-defsystem https://common-lisp.net/project/asdf/asdf.html#Defining-syst.... ASDF functions much like 'make' in that you've got a system definition listing the files belonging to your program. Whenever you call ASDF from the REPL, it'll look at what source files need to be (re)-built, compile them to FASLs, and (re)-load them into the running process. In contrast with C (but similarly to Python), Lisp allows code to be loaded into a running image. In the Lisp workflow, you don't restart the program you're writing each time you recompile (although you can, if you want). Instead, you keep it running, and load or re-load code into it as you work on it.
- _ph_ 10y agoYou can build your Common Lisp programs from a set of files like any other programming language. "asdf" is the most common system which provides loading complex lisp system. I actually use a makefile to build my Common Lisp based executables from my set of files, no neeed to build up an in-memory state. The difference with Common Lisp is, you are not limited to this build model, but while your whole code is loaded, you can keep redefining functions for development. This creates the minimal cycle of editing and testing any single function in your program. This is a big asset in development, but in no way means you have to build your systems that way. Actually the contrary, I can only recommend to restart your lisp image frequently to ensure the system loads and builds from file rather than depending on the image state.
- mikelevins 10y agoAs other people have said, you can use Lisp the same way you describe using Python or the same way you describe using C. You also have a third option: you can use Lisp as a sort of interactive command-line calculator-plus-kitchen-sink. Leave it running and teach it to do odd jobs for you. If you accumulate your odd jobs into a file then you'll have them for later. You could of course save the state of the running Lisp, but a source file is better in that it keeps a nice tidy record of the source code of your hacks. Serious programs written in Lisp are mostly organized pretty much like serious programs written in other languages: the program is factored into a collection of source files that, in the best case, reflects a logical decomposition of the functionality. There's some form of system loader that compiles and loads the sources in the right order and, if desired, dumps the result into an executable program. Nowadays most people use ASDF for system loading and dumping, I think, but it's not hard to write your own system loader, and I still know people who prefer to do it that way. Just as an example, CCL still uses its own homegrown loader to build. If your program is like a Python script then it's a Lisp source file that you pass to the Lisp kernel, in just the same way you would do it in Python. If it's a compiled executable, then your sources were compiled into the Lisp and dumped to that executable, and it works pretty much like a C program. The main difference is that there is no distinguished main(); instead, Lisps generally treat the Lisp's own repl as the default main function, and the image-dumping tools offer you the option to substitute the main function of your choice. Things are a little different, but only a little, and it's pretty easy to learn how they work.