freenode/#lisp - IRC Chatlog
Search
14:44:06
jmercouris
so you can use flet to return a function that has the contxt of a parent function, like some sort of closure factory?
14:45:01
pfdietz
Yes, function values (lambdas, too) can cause the context to be preserved, even after the parent function returns.
15:00:00
jcowan
A simple case. There are many functions in CL that take functional arguments, the most ordinary case being map, which passes the elements of a sequence through a function in order to form a sequence of the results.
15:04:58
jcowan
It's not uncommon for the function you pass to involve some of the local context of the call, as in (map 'list (lambda (x) (eq? x y)) some-list)
15:05:55
jcowan
This will return a list of booleans indicating whether each member of some-list is the same object as whatever y may be.
15:08:53
Shinmera
Is there a standard way of determining whether a float is negative? (keep in mind the case of -0.0)
15:13:07
pfdietz
(let ((x -0.0)) (and (<= x 0.0) (not (eql x 0.0)))) ==> T if -0.0 and 0.0 are "different"
15:15:06
Shinmera
The spec mentions this explicitly even: If an implementation supports positive and negative zeros as distinct values, then (eql 0.0 -0.0) returns false. Otherwise, when the syntax -0.0 is read it is interpreted as the value 0.0, and so (eql 0.0 -0.0) returns true.
15:15:16
jcowan
Another approach is to rely on the fact that (sqrt -1+0i) is i, whereas (sqrt -1-0i is -i)
15:18:44
jcowan
A less heavyweight approach is to take 3/x where x is 0.0 or -0.0, which will produce +inf.0 and -inf.0 respectively
15:21:05
jcowan
The spec allows (/ 3.0 0.0) to return +inf.0 (or however you want to spell it) rather than an exception
17:58:22
fraktor
I'm pretty new to lisp, and I've been trying to learn using SBCL. Is there a (relatively easy) way to make a mostly-portable executable out of lisp code?
18:00:13
aeth
fraktor: Usually you keep one session running, often in an IDE like in SLIME on top of Emacs. Then you launch everything from that session.
18:00:46
aeth
Obviously if you're going to e.g. distribute a desktop application then you'd need to build a standalone executable, though.
18:01:26
HighMemoryDaemon
fraktor: There's also Chicken. It's a Scheme, produces C code, and creates an executable from that. https://call-cc.org/
18:02:18
aeth
Even if you're running a server in production, though, I'd personally assume you'd be running it from the REPL. Standalone executables (afaik) ship the entire implementation so that's for if you don't assume one is already installed.
18:03:59
Bike
pfdietz: guessing at likelihood of delivering something to someone else basedon "I'm pretty new"
18:07:08
fraktor
I would like to be able to distribute programs to other users without making them install sbcl.
18:07:55
Bike
sometimes we get people in here who expect a compile-run cycle like with gcc, and that doesn't work, is all
18:09:45
fraktor
Bike: That's certainly what I'm used to. I've used REPLs for other languages, but not usually with a running program.
18:10:09
pfdietz
If you want to deliver a command line program, you will have some lisp function that gets called on program invocation. You can call this function (or one that it calls after argv parsing) when running your program from the REPL, as you would likely be doing during development.
18:11:27
pjb
Popularisation of Lisp will have to pass thru linux distribution of widely _USED_ lisp software, compiled with a toolset simiar to that of gcc.
18:11:38
aeth
it would look something like this in SBCL: sbcl --noinform --non-interactive --load foo.lisp --eval "(foo:main)"
18:12:09
aeth
foo is the package name and must be included, and main is just a convention so people know where to look for a function like this
18:12:17
pjb
Only once people will notice that several of their unavoidable tools are written in CL, will they start to be interested by and use Common Lisp.
18:12:25
aeth
I probably should have said foobar.lisp to emphasize that the filename and the package name can be different
18:21:51
aeth
pjb: Does your program allow certain implementation-specific flags to be set? e.g. sb-ext:*derive-function-types*
18:38:40
pjb
aeth: I try to avoid writing implementation dependent programs. This driver uses clisp. It would have to be rewritten using portability libraries…
18:54:33
jcowan
FWIW, ten Schemes deliver standalone executables, 8 by compiling to C and 2 by clever packaging of their regular runtimes.
18:58:26
gendl
LispWorks can deliver a "console image" at least as a single file (and probably a full-blown application although I don't have enough experience with LW).
18:58:36
jcowan
Quoth CLiki page: "Another form of disk image requires a copy of the particular Lisp implementation to be installed on the recipient's machine."
18:58:53
pjb
Well, this is FreeNode. We don't know any specifics of Commercial implementations. Only some echoes.
19:00:43
jcowan
pjb: No, obviously not. I said that at least one could do so in the past, which is true. I was not claiming any superiority of Scheme here, merely offering facts.
19:01:36
pjb
jcowan: you're offering wrong facts. Most implementations can deliver stand alone executables. You would have to spend half an hour researching implementations to find a strange one that cannot.
19:01:50
fe[nl]ix
jcowan: that sentence doesn't say that the the implementation requires that, but only that the particular form of disk image does
19:02:10
younder
Snap packaging can round all dependencies up in a nicke packet so you are less dependent on that on file problem. (look up SNAP)
19:02:30
fe[nl]ix
jcowan: in other words, that there are images that are disjoint from the CL runtime that is required to start the image
19:04:06
gendl
jcowan: but statements like "at least one CL has done so in the past" are vague and misleading.
19:04:33
gendl
I do think this is more of a problem with outdated content cluttering up Cliki than a problem with any actual reality.
19:05:49
jcowan
gendl: I grant that my remark was misleading, as obviously several people have been misled by it.
19:08:07
jcowan
I would be interested to know if there are any implementations today that can generate {C,JavaScript,whatever}.
19:09:41
shka_
jcowan: not sure about that, but from what i understand it goes directly into bytecode
19:10:35
jcowan
Yes, that's what I would expect. It's on the whole easier to generate bytecode than Java.
19:10:35
phoe
How do I make postmodern output timestamps as non-integers? I need higher resolution than integers.
19:10:36
minion
phoe, memo from shka_: czy mógłbyś mi dać znać czy masz jakiś problem z treścią mojego nowego posta? Chcę opublikować w tą sobotę (dopiszę tylko kod demonstrujący)
19:11:01
phoe
Loading simple-date after loading postmodern doesn't change anything, (postmodern:query "SELECT now();") ;=> ((3748964957))
19:11:54
jcowan
whereas it is on the whole harder to generate machine code than C, and it is subject to possible obsolescence issues
19:12:06
shka_
phoe: first of, you have to ensure that correct column type is set up in the postmodern
19:13:24
phoe
shka_: the examples at https://sites.google.com/site/sabraonthehill/postmodern-examples/postmodern-time-functions don't say anything about column types.
19:21:35
phoe
I found a system called :cl-postgres+local-time but loading it doesn't change anything
20:11:26
younder
Do any of you have any experience with template Haskell. Is so how do they compare to CL macro's.
20:12:56
jasom
younder: as most non-lisp metaprogramming there is extra overhead of having to learn a second language, as the AST of haskell is a very different representation than haskell is usually programmed in.
20:14:50
oni-on-ion
i'd say the type system of haskell is much more powerful and closer to macro than TH.
20:18:51
oni-on-ion
prolog i set right next to lisp for macro, not sure about scheme and hygenia, but julia right below it because im still a newbie with it
20:22:36
jasom
hmm; python lets you manipualte the AST, but I don't know that it makes it homoiconic; we may be getting OT at this point going too-far down the Julia path
20:22:45
oni-on-ion
although there is one thing, if you have a macro 'john' and want to call it, @john is how. i forget the reasoning behind this but i think it is just syntax sugar. not sure where CL stores its own macros; in the function slot ?
20:23:55
jasom
In a homoiconic language, the primary representation of programs is also a data structure in a primitive type of the language itself. <-- obviously this doesn't just mean AST, otherwise all self-hosting languagese would be homoiconic (assuming the compiler or interpreter parses to an AST at some point)
20:26:19
oni-on-ion
i am really not sure about julia macros. have to play with it more, the manual is too dry
20:26:27
jasom
oni-on-ion: all lisps can use symbols for many things; lisp-1 v lisp-2 is just a question of if the function-call position is separate from the value
20:28:14
jasom
lisp-1 v lisp-2 is a question of (X X) <- does X represent the same thing when this is evaluated.
20:29:49
oni-on-ion
that is the second thing i like about scheme. which julia was written in (chez) but anyhow, homoiconicity to me is extremely important for 'real' macros. and to 'flip the switch' with quote/unquote
20:31:08
jasom
and of course if you make a hash table that is keyed with symbols, you've added a new namespace.
20:31:29
oni-on-ion
jasom: and also very important for the ability for anaphoric macros =) as nickname reminds me
20:32:21
oni-on-ion
change package, change namespace. wouldnt that count for 'how many namespaces' there are
20:33:25
anamorphic
From page 836 (apparently, I don't have my copy in front of me) of PAIP he says Common Lisp has 7 namespaces
20:33:29
jasom
oni-on-ion: that's because symbols are string-designators, and defpackage/in-package take string designators
20:36:48
jasom
oni-on-ion: don't forget that symbols are upcased so you need to do e.g. (in-package "CL-USER")
20:38:14
jasom
oni-on-ion: if packages were named as symbols, you might see code written like this https://github.com/jasom/spm-reader/blob/master/spm-example.lisp (I wrote a proof-of-concept reader macro that uses symbols to name packages, with the keyword package being the root namespace)
20:39:30
oni-on-ion
whoa that is trippy, is this file copied twice ? if i page up/down in emacs it looks the same.
20:40:15
oni-on-ion
i see 4 of the same thing, my dyslexia is acting up and im starting to see moire patterns
20:40:44
jasom
oh, the first line of each are: json:encode, clj:encode-json, :yason:encode, :cl-json:encode-json
20:43:19
_death
I think he wants a macro to "abstract" the 4 forms.. not realizing it would serve no purpose but obfuscation
20:44:52
aeth
oni-on-ion, jasom, etc.: You can't do "FOO-BAR" and be fully portable. If you use literal strings you have to generate them at read time with #.(symbol-name '#:foo-bar) to get "FOO-BAR"
20:47:23
_death
aeth: someone who changes the readtable case and expects things to work is deluding himself
20:48:11
aeth
_death: As long as the readtable case doesn't change *multiple* times during the execution of the program #.(symbol-name '#:foo-bar) will work.
20:49:42
jasom
aeth: if the readtable case has been changed, then #.(symbol-name '#:cl-user) will not work.
20:49:49
aeth
oni-on-ion: I use it everywhere in my code, e.g. if I wanted to prefix foo- in a macro I would use #.(symbol-name '#:foo-)
20:50:02
jasom
if it's e.g. case-preserving then it will look for "cl-user" which is not required to exist, while "CL-USER" *is* required to exist.
20:50:41
jasom
I'm fine with #. for such short uses, but in this case it's flat out worse than using a string, as a string will always be right.
20:52:13
jasom
also (in-package #.(symbol-name '#:foo)) is going to be identical to (in-package '#:foo) since there is an implicit call to symbol-name (probably via cl:string) in the in-package macro
20:52:31
aeth
_death: There are two acceptable uses for #. imo. symbol-name (like above) and to get a constant number in an unquoted type specifier like (let ((bar 42)) (check-type bar (integer 0 #.(isqrt most-positive-fixnum))) bar)
20:53:15
_death
aeth: in most-positive-fixnum that may work.. in your own constants that may not depending on when you define them
20:54:06
aeth
_death: Just wrap the constant in eval-when and that fixes it, at least for CCL, which does complain about such things. But almost all of the time it will be something like most-positive-fixnum
20:54:17
oni-on-ion
shift 3 dot shift 9 symbol-name quote shift 3 shift semicolon foo shift 0 shift 0 ..... thats a lot of dang-ed typing !!
20:55:55
aeth
_death: something like this: (defun fixnum-square (number) (check-type number (integer 0 #.(isqrt most-positive-fixnum))) (expt number 2))
20:56:22
jasom
aeth: I'm also trying to figure out why you are using #. for the symbol-name; symbol-name 'foo will never change since foo is read in once; is it just an optimization?
20:59:40
aeth
jasom: I've been doing this for a while now but I believe that the reasoning was to get the performance of "FOO" but with more reliability. I don't think it would make a difference in SBCL, though.
20:59:58
aeth
At the very least SBCL seems to turn (defun foo () (symbol-name '#:bar)) into a function that constantly returns "BAR"
21:05:41
aeth
Why specify a boundary? All that's required is to prove to the compiler that is remains a fixnum so the arithmetic stays inline. The actual bounds are your memory and patience.
21:06:01
aeth
It would be impossible to leave fixnum with that algorithm, though, because you would certainly run out of memory.
21:09:15
younder
The marshaling and representation stands the potential of being a major bottleneck.
21:15:04
aeth
No, what I actually care about is generating the primes as quickly as possible. I would rather have every implementation generate as many as it is capable of doing efficiently than artificially limit 64-bit SBCL or create a misleadingly high bound for the rest.
21:15:55
aeth
I can use fixnum, I can create something that is efficiently only in 64-bit SBCL, or I can artifically limit what 64-bit SBCL is capable of doing. (This is the case because 64-bit SBCL has the largest fixnum.)
21:16:02
_death
but, if you have an array of things, then you don't care about fixnum, but a subtype of it
21:19:39
aeth
Don't run a high-performance prime sieve on a 16-bit CL with the standards-specified 16-bit-friendly absolute minimums for everything, then.
21:22:00
aeth
If you use double-floats in a computationally intensive way, CLISP exists to make your life hell.
21:25:07
aeth
In general, though, in my personal experiences, code involving numbers will run almost instantly in SBCL, may run almost as fast in SBCL or have unexpected slowdowns in CCL, will sometimes be much slower in ECL, and will usually be basically unusable in CLISP.
21:28:26
aeth
Hypothetical 16-bit everything-is-the-minimum-in-hyperspec Common Lisp would be even worse than CLISP here. And I'm pretty sure I have some docstrings longer than 1024, which would also not be conforming.
21:29:51
aeth
Okay, the longest docstring I can think of in my code is 749, but it will probably pass 1024 at some point as more details are added. That will no longer be fully portable. Will I limit myself to 1024 character docstrings? Absolutely not.
21:30:08
_death
so my approach would be to give bounds, and if an implementation can't generate efficient code for that bound, so be it, don't use them if you expect something fast, but at least they won't break..
21:33:04
aeth
_death: So your approach would either (1) make code that's only fast in SBCL or (2) artificially limit SBCL so you can at least support CCL and maybe a few others similarly. Depending on whether your bounds are SBCL-friendly or CCL/etc.-friendly.
21:33:51
aeth
_death: If you want #2 you can write a trivial inline function with a lower CHECK-TYPE.
21:35:26
aeth
anamorphic: The standard permits 16-bit implementations (otherwise it wouldn't have ridiculously low minimums like 1024 for arrays, which include strings)
21:36:38
aeth
They were probably slow, barely usable, not very useful, and a subset of the language. Almost certainly made for the old CL, pre-CLOS.
21:39:54
_death
but again, in this specific case you actually care about array length, not about fixnum.. even if you don't have explicit bounds to specify, fixnum is often a poor candidate
21:45:11
aeth
_death: This is low level code that would ideally produce efficient code in any reasonable implementation. If you want a constant interface so (foo n) will work for any constant value n in a program, wrap it with a trivial inline function that establishes a second set of bounds. The inner function has bounds that produces efficient code (keeping it fixnum).
21:46:02
aeth
_death: You cannot go the other way around and make an efficient function from one that either artificially limits SBCL or produces code that's only efficient on SBCL (since intermediate values might become bignum in the other implementations).
21:47:02
aeth
_death: It's possible in some strange cases, the part that keeps it fixnum for efficient fixnum arithmetic won't line up so one of the arrays will be created too large. This isn't C, though. You'll get an error there.
21:47:39
aeth
If for some reason that shows up in an implementation (unlikely), then that's the time to spend the time addressing it.
21:51:08
aeth
I don't even check for bounds with my float functions in general because that would greatly slow things down because there are too many of them (think things like vec+). I do find and document them, though.
21:52:05
aeth
A user who cares could wrap the functions or, more ideally, wrap a function that uses several of these and derive the final safe input bounds (and it's actually unnecessary here because you'll get an overflow/etc. error at some point unless you turn off float traps... and the documented bounds just document what causes *these*)
21:53:35
aeth
But in general, when I work with integers they're either (1) trivial enough that I'll just inline them and bignums are OK if that's what you want or (2) nontrivial enough that fixnums or (un)signed bytes of size 32 or 64 are imo the right thing. Usually the latter two these days, actually.
21:58:23
_death
if you generate two versions of code, for fixnums and bignums, that's good and non-fragile.. that's how CL works..
21:58:24
aeth
There is one place where I use fixnums very incorrectly, though. I use them as the type of a vector index. Afaik array-dimension-limit should be the bound instead, which in SBCL is off by 2 (in practice, no difference since you'll run out of memory before getting to those 2). So the type alexandria:array-index
22:07:15
aeth
Hmm, in CCL a fixnum is about 16x larger than array-dimension-limit... but again, you'll run out of memory first because array-dimension-limit, assuming a *bit* array, would make that array be about 8 PiB or 9 PB
22:08:21
aeth
(And, for semi-completeness, ECL's most-positive-fixnum is its array-dimension-limit.)
22:18:25
aeth
This seems to be fairly common: (let ((foos #(1 2 3))) (loop :for foo :across foos :for i :of-type alexandria:array-index :from 0 :do (format t "~D ~S~%" i foo)))
22:18:53
aeth
Of course it'll probably not have a type, or it will incorrectly have the type fixnum if there is one... and it probably won't be optimized
22:21:11
aeth
Yes, but it could be optimized. Without the type declaration, the compiler will not know enough to realize that i cannot be a bignum, and with the type declaration of array-index or fixnum, there will be a type check every iteration.
22:21:53
aeth
The type declaration is probably the way to go if you're doing something fancier with it... but the type declaration shouldn't be necessary for it to be known that it's not a bignum.
22:23:06
aeth
(It's probably actually better to use fixnum here than array-index because the fixnum type check might be faster.)
22:24:47
_death
I would write this as (dotimes (i (length foos)) (format t "~D ~S~%" i (aref foos i))) btw
22:25:36
aeth
_death: It's hard to come up with a trivial LOOP that demonstrates something about LOOP without the LOOP itself being unnecessary.
22:28:47
aeth
Conditional collect/append is probably the only place where a somewhat trivial LOOP is actually the nicest way to write it.
22:29:38
_death
a "smart enough compiler" could deduce that I is of type array index.. loop or no loop, but of course you don't want to rely on a mythical compiler if performance is important
22:32:22
aeth
_death: But how would you work around something like that other than turning safety off (assuming that even turns safety off)? I guess the way in the loop would be to do :from 0 :to (length foos) except that might now do two end condition checks when one will do
22:33:20
aeth
The equivalent map nil with an outer i variable will behave very similarly, including potentially having optimized access for iterating across vectors. dotimes might actually be the most efficient here, but only when the bounds of foos are known.
22:33:56
aeth
_death: I guess my point is only the sufficiently smart compiler will have this optimized at all, so you would have to rely on the "mythical compiler" for maximum performance here.
22:38:03
aeth
Compilers already include AI. For example, style-warnings are 'automated code review', which should be a pretty hot field of AI, right?
22:42:47
_death
quite an interesting page from historical perspective https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node91.html
23:08:42
jcowan
Compilers are "automatic programming", one of the first AI fields. In fact, so are assemblers.
23:48:55
jasom
has anyone tried writing an ASDF plugin that lets you specify a particular lisp file should be loaded with a particular read-table?
23:50:42
jasom
It seems obvious enough that *someone* must have looked into it. I was just mulling over racket's language modules and considering how I might implement something similar in CL.
23:53:32
scymtym
jasom: fare's syntax-control (i think that was the name) branch would probably be good starting point
23:54:41
jasom
scymtym: that branch had different purposes; I was thinking of just defining a new component type
23:55:39
jcowan
IMO TRT is to allow specifying the version of read that the compiler/loader/eval uses
0:04:47
aeth
jcowan: That example actually survived in the HyperSpec. http://www.lispworks.com/documentation/HyperSpec/Body/m_prog_.htm
0:44:03
no-defun-allowed
I wouldn't trust shit on codeproject tbh. People who call themselves coders are probably losers.
0:47:13
aeth
LdBeth: There's an argument there, it's just that the author doesn't know Lisp. e.g. ":type float" is probably not what you'd ever want to use since it's basically (or short-float single-float double-float long-float) and probably won't get you anything over ":type number" (or maybe even ":type T"!). If you're going to use a float in a struct, you probably want a specific type of float. The author probably meant "single-float" and was think
0:50:22
aeth
No surprise that the author primarily knows Clojure. Clojurists seem to have the wrong idea of how Common Lisp works but seem to think that they know how Common Lisp works.
0:52:28
aeth
And, yes, the author has no mention of specialized arrays as an option (or multiple return values!), which is strange.
0:53:52
aeth
(I didn't mean to insult Clojure programmers, although in hindsight I see how it could seem this way... let me just put it differently: I know I don't know Clojure, so I don't blog about Clojure's weaknesses. Plenty of Clojurists who don't know CL seem to blog about CL's weaknesses.)
0:54:43
LdBeth
aeth: I didn't noticed the type thing. But I mean, tuple is more close to vector and any saner (Common) Lisper would use vector ranther than list for it
0:55:44
aeth
It's pretty strange that the author argues that Python, Ruby, and JavaScript are more popular than Lisp because Common Lispers don't use statically typed structs very often.
0:57:59
aeth
LdBeth: There is a point that could be made in a similar essay. There is a long tradition in Lisp of people using lists when they are completely and totally inappropriate. e.g. 2.2.4 in the famous Worse is Better essay. http://dreamsongs.com/WIB.html
1:01:10
LdBeth
aeth: It is sometimes understandable because the writer wants it to be comaptble with other dialects, especially for someone had used MacLisp or InterLisp for a while
1:07:20
aeth
This means that he tested it in something other than SBCL, one which doesn't do type-checking in the struct constructor. I'm betting CLISP.
1:13:56
jcowan
I'd say he thinks that because he declared the slots to be floats, he assumes the constructor will cast its arguments to floats
1:14:33
aeth
jcowan: But then he prints it out, which should then make that assumption very clearly disproven
1:15:44
oni-on-ion
are they ever out of order? i wouldnt assume any of them optional given the name 'vec3d'
1:16:52
aeth
oni-on-ion: There are two common approaches for this sort of thing (vec3s). One is to use a specialized array, and the other is to use defstruct to define a specialized array rather than to define a struct. The result is basically the same, except the latter automatically creates accessors (but not a type, which is strange because defstruct normally defines a type and the type can still be useful if it's a specialized array)
1:18:23
aeth
oni-on-ion: I use a macro to make my own specialized array instead of using defstruct. I call it define-array-and-type: https://gitlab.com/zombie-raptor/zombie-raptor/blob/b90f23cf6168f892fce8fd980649eaf882662acb/util/array.lisp#L55-67
1:19:04
aeth
e.g. (define-array-and-type vec3 (single-float '(3)) (x y z)) and then (vec3 1f0 2f0 3f0)
1:19:23
jcowan
Tuples make sense in the context of destructuring-bind, but without such things, not so much
1:19:57
jcowan
The point of a tuple is that it is both heterogeneously typed (in the sense that every object in it has a known type) and indexable.
1:23:43
aeth
You could, if you assume tuples to be immutable, use a macro on top of defstruct to build tuples for CL since defstruct also has :read-only for each slot (just set every slot to read-only). Of course, the compiler won't optimize it because it's not a common idiom.
1:23:47
jcowan
I have been seeing in my current job how people who have never used dynamically typed languages are actually afraid of code written in them, and I think this is an example.
1:27:21
cgay
I'm not that familiar with defstruct. Can you really use it to implement tuples, which have unbounded length?
1:30:00
jcowan
Terminology is loose, but most people talk about tuples as being of a particular length: there are pairs, triples, quadruples, ....
1:30:10
aeth
cgay: Hmm... If you need unbounded length tuples, you could create the tuple on demand with deftuple if it doesn't currently exist.
1:30:59
jcowan
The result is nominally rather than structurally typed, but that really is a fine detail.
1:31:25
jcowan
"tuple" doesn't necessarily mean "immutable tuple"; in Python it does, but not everywhere.
1:34:01
jcowan
in Maclisp hunks were mutable in content, immutable in size, and had to be a power of 2.
1:34:10
cgay
Interesting because just yesterday I was noticing that in Dylan <stretchy-collection> is not a subclass of <immutable-collection>.
1:35:44
cgay
Interesting because just yesterday I was noticing that in Dylan <stretchy-collection> is not a subclass of <mutable-collection>.
2:24:18
HighMemoryDaemon
Does most people's Lisp programming session (At least Emacs users) start by doing the follow? : Open Emacs, Open your project's ASD file, M-x slime, C-c C-c l (load file to Slime), (cl:quickload 'my-project)
2:36:22
HighMemoryDaemon
oni-on-ion: You don't need to 'C-c C-c l' the ASD file if you are in the folder that contains all your projects?
2:41:53
HighMemoryDaemon
Very nice, so changing directories with eshell wouldn't even matter since QuickLisp looks in the local-projects folder by default.