> In article <20120217012534....@kylheku.com>,
> Kaz Kylheku <k...@kylheku.com> wrote:
>> On 2012-02-08, Waldek Hebisch <hebi...@math.uni.wroc.pl> wrote:
>> > Well, I would like symbols to have life independent of any package.
>> > Packages then would be mapping from symbols to variables. I would
>> > prefer Lisp-1 so I wrote variables, but of course you get Lisp-2
>> > if you have parallel mapping from symbols to functions. Also,
>> That's inadequate because not everything that needs to be named
>> by a symbol and put into a package is a function or variable.
>> Your package system needs to support additional namespaces like
>> classes.
> That's not a problem. Just add more top-level environments. See the > lexicons implementation for an existence proof.
>> Plus it has to be user-extensible to new spaces.
> See above. Because lexicons are first-class objects you can create as > many of them as you want.
>> > I believe that such Lisp would be better than Common Lisp.
>> I believe you drank too much cough syrup this morning.
>> A symbol should be enough to resolve the question of identity. Under your
>> system, a symbol is no longer enough to identify. It requires a package.
>> Now everything becomes complicated. For instance FIND-CLASS cannot just
>> take a single argument, because a symbol only identifies a class within
>> some package. It has to be (find-class symbol package).
> This is true of Common Lisp as well, it's just that the ambiguity arises > at read-time, and is resolved by the read-time value of the global > variable *package*. The same solution can be used at compile time or > run-time.
This violates the principle of: do not move into run-time what is
adequately and trivially solved at read time.
(How far do you take this silliness? Why don't we look for closing
parentheses at run time also.)
>> Or worse; (find-class symbol) --- package is implicit somehow based
>> on where the call occurs, ugh.
> In CL, package is implicit depending on how symbol was constructed, but > a typical scenario is:
> (find-class 'symbol)
> where the symbol is constructed by the reader and package is implicit > depending on the value of *package* when that form was read.
I.e. package is no longer implicit at the time the find-class is being run.
The symbol is done. We don't have to /think/ about the package as it relates
to FIND-CLASS (because it doesn't, in any way).
> How you can find that any less distasteful is a mystery to me.
You can find that less distasteful precisely because read-time is a simple
processing phase that you can forget about once it is done, and just think
about the resulting symbols (which are exactly like symbols in a Lisp that
has no package system.)
Never do at run time what can be perfectly taken care of at read-time.
Whenever static can completely "pwn" dynamic, we should support static.
Compiling beats interpreting; macros kick the crap out of fexprs. (OTOH, dynamic typing kills static, so screw that.)
These little package annoyances exist for those who insist on programming
at the REPL. Programmers who put code into files and build their programs
don't see any of this "oh oh, I interned a symbol and now there will be
a clash."
Which is why I have never been bitten by these problems; I generally do not
not use REPLs. Even when experimenting with code, I put it into small
files and load those.
Any signficant programming should never be done outside of the context
of a version control system anyway. Just being able to do a diff between
experiment and the last working version is darn useful.
You will never achieve a REPL in which you cannot screw up so badly that
it's not easier to just kill the image and start with a fresh one.
Packages are not really at the root of this problem. It's the REPL itself.
Whenever I use a REPL for anything more complicated than evaluating a few
expressions, I get bitten by the fact that it's a write-only black hole
way sooner than I can get bitten by any package-related issue.
Kaz Kylheku <k...@kylheku.com> writes:
> Whenever I use a REPL for anything more complicated than evaluating a few
> expressions, I get bitten by the fact that it's a write-only black hole
> way sooner than I can get bitten by any package-related issue.
Quoting Zach quoting Rob Warnock: Use the Lisp environment to make your
life easier!!!
> On 2012-02-17, RG <rNOSPA...@flownet.com> wrote:
> > In article <20120217012534....@kylheku.com>,
> > Kaz Kylheku <k...@kylheku.com> wrote:
> >> On 2012-02-08, Waldek Hebisch <hebi...@math.uni.wroc.pl> wrote:
> >> > Well, I would like symbols to have life independent of any package.
> >> > Packages then would be mapping from symbols to variables. I would
> >> > prefer Lisp-1 so I wrote variables, but of course you get Lisp-2
> >> > if you have parallel mapping from symbols to functions. Also,
> >> That's inadequate because not everything that needs to be named
> >> by a symbol and put into a package is a function or variable.
> >> Your package system needs to support additional namespaces like
> >> classes.
> > That's not a problem. Just add more top-level environments. See the > > lexicons implementation for an existence proof.
> >> Plus it has to be user-extensible to new spaces.
> > See above. Because lexicons are first-class objects you can create as > > many of them as you want.
> >> > I believe that such Lisp would be better than Common Lisp.
> >> I believe you drank too much cough syrup this morning.
> >> A symbol should be enough to resolve the question of identity. Under your
> >> system, a symbol is no longer enough to identify. It requires a package.
> >> Now everything becomes complicated. For instance FIND-CLASS cannot just
> >> take a single argument, because a symbol only identifies a class within
> >> some package. It has to be (find-class symbol package).
> > This is true of Common Lisp as well, it's just that the ambiguity arises > > at read-time, and is resolved by the read-time value of the global > > variable *package*. The same solution can be used at compile time or > > run-time.
> This violates the principle of: do not move into run-time what is
> adequately and trivially solved at read time.
> (How far do you take this silliness? Why don't we look for closing
> parentheses at run time also.)
We have an honest difference of opinion about what constitutes the problem being "solved." IMHO a parser that mutates global state is not a solution.
> >> Or worse; (find-class symbol) --- package is implicit somehow based
> >> on where the call occurs, ugh.
> > In CL, package is implicit depending on how symbol was constructed, but > > a typical scenario is:
> > (find-class 'symbol)
> > where the symbol is constructed by the reader and package is implicit > > depending on the value of *package* when that form was read.
> I.e. package is no longer implicit at the time the find-class is being run.
Yeah? So? It is no longer implicit at run time when using lexicons either. In this respect the two approaches are equivalent.
> > How you can find that any less distasteful is a mystery to me.
> You can find that less distasteful precisely because read-time is a simple
> processing phase that you can forget about once it is done
But you can't forget about it. That's the whole point. The are common error situations where the reader mutates global state in ways that you don't want.
> These little package annoyances exist for those who insist on programming
> at the REPL. Programmers who put code into files and build their programs
> don't see any of this "oh oh, I interned a symbol and now there will be
> a clash."
First, that's not true. Even if you put your code into files you can still get bitten by the reader's mutating global state.
And second, one of the oft-touted features of Lisp is that it supports interactive exploratory development. A "solution" to a problem that discards one of the biggest (for some people) advantages of using the language in the first place is not a solution, IMHO.
> Which is why I have never been bitten by these problems; I generally do not
> not use REPLs. Even when experimenting with code, I put it into small
> files and load those.
Well, bully for you. I use the REPL. I like the REPL. I get a lot of leverage from the REPL. IMHO the REPL is one of the things that makes Lisp better than, say, Java. And I don't think I'm the only one who feels this way.
> Any signficant programming should never be done outside of the context
> of a version control system anyway. Just being able to do a diff between
> experiment and the last working version is darn useful.
> You will never achieve a REPL in which you cannot screw up so badly that
> it's not easier to just kill the image and start with a fresh one.
> Packages are not really at the root of this problem. It's the REPL itself.
Ah. Well. It seems that our disagreement runs even deeper than I thought.
> Whenever I use a REPL for anything more complicated than evaluating a few
> expressions, I get bitten by the fact that it's a write-only black hole
> way sooner than I can get bitten by any package-related issue.
Maybe you just don't know how to use the REPL properly.
BTW, note that "a REPL" is not synonymous with "a REPL that receives its input from GNU readline." I agree with you that such a REPL is not good for much more than casual noodling around. But that is not the only sort of REPL there is.
Maybe you have just never experienced a proper REPL.
> You can find that less distasteful precisely because read-time is a simple
> processing phase that you can forget about once it is done, and just think
> about the resulting symbols (which are exactly like symbols in a Lisp that
> has no package system.)
Actually, this is something I was thinking about. I don't want to defend the package system[*], but, for those of us who learned Lisp on implementations without any kind of namespace management, it is better than that, and it's also conceptually compatible with what those implementations did.
--tim
[*] on the other hand I think there are a lot of things which would be ahead of it if I had to make a list of things-to-fix, such as a standard sockets API for instance (with probable resulting need for a properly-sorted I/O API) and so on.
> Well, bully for you. I use the REPL. I like the REPL. I get a lot of
> leverage from the REPL. IMHO the REPL is one of the things that makes
> Lisp better than, say, Java. And I don't think I'm the only one who
> feels this way.
strongly agree with that. I live in a REPL for weeks.
> There is one (and only one) situation in which symbols with packages are
> actually necessary in CL (which is to say, in which it is not
> straightforward to provide equivalent functionality using compile-time
> constructs). I doubt most CL programmers even know what that situation
> is.
Language constructs are never "necessary" - the only thing that is "necessary" is Turing equivalence (and even that is not always the case).
I can think of at least two situations where the Common Lisp package system is /useful/:
1) With the Common Lisp package system, it's easy to make the correct distinctions between slots and slot accessors in classes that happen to have the same name: In Common Lisp this is extremely easy - they are the same slot exactly when they are named by the same symbol. In all other languages that provide some form of multiple inheritance, this is substantially harder and can cause real headaches.
2) The Common Lisp package system virtually removes hygiene issues from its macro system. The package system gives you a good way to precisely specify which symbols are known outside of a macro and which are not. Without the package system, you have to start introducing constructs for ensuring hygiene into the macro system (either low-level constructs, or "automatic" hygiene).
In both cases, the underlying language constructs (classes, macros) can remain relatively simple with the package system and just rely on symbol identity, but have to come up with their own name distinction mechanisms without the package system. This translates directly to other language extensions that you may want to add as libraries to the language: With the package system, you don't have to worry too much about naming ambiguities, but without the package system, you have to start designing additional features to deal with them for each and every extension.
If you argue for dropping the package system, and replacing it with something else, you need to provide an answer here...
I see. I wasn't aware (anymore) that you're suggesting a mapping between your lexicons to packages. Considering what you seem to think is the major problem with packages, this may still be overkill.
A problem in the way how you word your concerns is that you describe the package system as fundamentally flawed, but the package system is actually not the source of the problem you have. It's rather a detail of how the read algorithm in Common Lisp works.
What you suggest under the link above is essentially a different read algorithm, where symbols that cannot be found are not automatically interned, but rather patched up in such a way that they find their actual definition later on during evaluation. (This reminds me of the delayed finalization of CLOS classes, which ensures that superclasses don't have to be fully defined when a defclass form is evaluated.)
I guess this way of patching up / delaying symbol interning can probably be provided without the need to build a whole package system replacement around it. This could even be a compatible extension of Common Lisp (which doesn't really specify which read algorithm to use in a read-eval-print-loop anyway, as far as I can tell).
It's confusing that you criticize the package system for something that it is ultimately not responsible for. What you should be criticizing is Section 2.3.4 of the HyperSpec.
> 2) The Common Lisp package system virtually removes hygiene issues from
> its macro system. The package system gives you a good way to precisely
> specify which symbols are known outside of a macro and which are not.
This may be a bit off the thread.
I usually don't write anaphoric macros (not intentionally anyway :) )
But I have one macro in my unit test system that goes like this
I ask because all the noise about the specialty of a anaphoric macro and it's description in the books seem to miss out that the variables can be safely in different packages.
Even the variable capture stuff that is explained does not usually point this out (in the places I have read it). Or may be I missed it, cause I had to make this up when I needed it.
> I see. I wasn't aware (anymore) that you're suggesting a mapping between > your lexicons to packages. Considering what you seem to think is the > major problem with packages, this may still be overkill.
> A problem in the way how you word your concerns is that you describe the > package system as fundamentally flawed, but the package system is > actually not the source of the problem you have. It's rather a detail of > how the read algorithm in Common Lisp works.
I guess it depends on your definition of "fundamentally flawed." The whole point of having symbols in the first place is that they are automatically constructed when reading Lisp source code. You can construct a legal Lisp program without using the reader (except to bootstrap the process) by doing something like this:
So yes, it is technically true that my concern is (to a large extent) about "a detail of how the read algorithm in Common Lisp works." But it is IMHO a rather important detail.
> What you suggest under the link above is essentially a different read > algorithm, where symbols that cannot be found are not automatically > interned, but rather patched up in such a way that they find their > actual definition later on during evaluation.
No. Lexicons use the standard Lisp reader algorithm.
Lexicons are not "better packages." They are fundamentally different from packages. They map symbols (or to be strictly technically correct, identifiers, which in CL happen to be symbols) onto bindings. Packages map strings onto symbols. Lexicons are first-class global lexical environments. Packages are hash tables from strings onto symbols.
Lexicons do what they do at macroexpand/compile time. Packages (mostly) do what they do at read time. They are as different as two computational concepts can be. If you do not see that then you do not understand what lexicons are.
> (This reminds me of the > delayed finalization of CLOS classes, which ensures that superclasses > don't have to be fully defined when a defclass form is evaluated.)
Yes, delayed binding of lexical references is very similar to many other forms of delayed binding in Lisp, and has many of the same advantages.
> I guess this way of patching up / delaying symbol interning can probably > be provided without the need to build a whole package system replacement > around it. This could even be a compatible extension of Common Lisp > (which doesn't really specify which read algorithm to use in a > read-eval-print-loop anyway, as far as I can tell).
Lexicons ARE a compatible extension to Common Lisp, since they are implemented in (mostly) portable Common Lisp. (That this is possible is a sterling credit to the overall design of the language.)
> It's confusing that you criticize the package system for something that > it is ultimately not responsible for. What you should be criticizing is > Section 2.3.4 of the HyperSpec.
The idea of the package system being "responsible" for anything strikes me as a little bizarre.
What I am criticizing is one aspect of Common Lisp's design. It is an aspect that involves elements of the reader, the package system, and indeed the whole concept of symbols and symbolic programming (though I don't often highlight that. I have learned over the years that one must pick one's battles.)
The real fundamental problem, as succinctly as I can state it, is this: state in general is bad software engineering practice, to be avoided whenever possible (it's not always possible). GLOBAL state is even worse and it is to be even more assiduously avoided. And global state that is mutated by the language parser is a Really Bad Idea. It leads to real problems of the sort that sends newbies to C.L.L. with the same questions year in and year out, and makes the Idiots Guide to CL Packages such a perennial best seller on the page rank circuit. It also leads to experienced Lisp programmers arguing over whether they should be writing :FOO or #:FOO or "FOO" in their defpackage forms.
Whether that is a criticism of packages or the reader or something else is in the eye of the beholder, and in any case quite beside the point.
The point is: there's a problem. Reasonable people can disagree over how serious this problem is or what (if anything) should be done about it. But that there is a problem is undeniable. (Note that "there is no problem" and "there is no problem FOR ME" are not equivalent statements.)
> Whether that is a criticism of packages or the reader or something else
> is in the eye of the beholder, and in any case quite beside the point.
> The point is: there's a problem. Reasonable people can disagree over
> how serious this problem is or what (if anything) should be done about
> it. But that there is a problem is undeniable. (Note that "there is no
> problem" and "there is no problem FOR ME" are not equivalent statements.)
Yes, there is a problem. However, the concept of mapping strings to symbols is in general more expressive, and hence superior to mapping symbols to bindings. Any suggestion for solving the problem that favors the latter over the former is a loser.
Lisp, and especially Common Lisp, is about making complex problems easier to solve, not about making easy problems easy to solve. Packages are in line with that.
> > 2) The Common Lisp package system virtually removes hygiene issues from
> > its macro system. The package system gives you a good way to precisely
> > specify which symbols are known outside of a macro and which are not.
> This may be a bit off the thread.
> I usually don't write anaphoric macros (not intentionally anyway :) )
> But I have one macro in my unit test system that goes like this
Yes. But it's not anaphoric :-) It's only anaphoric if the macro binds something that is then referenced in the macro invocation.
An anaphoric macro invocation looks like:
(aif (some-computation) (do-something-with it))
The apparently unbound reference to IT is (presumably) bound by AIF.
This actually points out another problem with packages: symbols with the same name conflict with each other whether or not they have any bindings that would actually conflict.
So if you want to say:
(aif (something) (f it))
as opposed to:
(anaphoric:aif (something) (f anaphoric:it))
and you also want to define a function called IT, you can't do that safely using packages. You can do it safely using lexicons, because conflicts are resolved separately in each namespace.
In article <9qakhoFju...@mid.individual.net>,
Pascal Costanza <p...@p-cos.net> wrote:
> On 18/02/2012 21:38, RG wrote:
> > Whether that is a criticism of packages or the reader or something else
> > is in the eye of the beholder, and in any case quite beside the point.
> > The point is: there's a problem. Reasonable people can disagree over
> > how serious this problem is or what (if anything) should be done about
> > it. But that there is a problem is undeniable. (Note that "there is no
> > problem" and "there is no problem FOR ME" are not equivalent statements.)
> Yes, there is a problem. However, the concept of mapping strings to > symbols is in general more expressive,
No, it isn't. I have made no commitment about what kind of bindings are associated with identifiers via lexicons, and indeed one of the features of lexicons is that one need not make any such commitment because you can create new lexicons and hence new kinds of bindings at will. So one possible mode of deploying lexicons is where every identifier has a single kind of binding (per lexicon), and that binding is a symbol.
That design is isomorphic to CL's current design and hence cannot possibly be any less expressive than CL. (It can, however, be implemented without packages!)
> and hence superior to mapping symbols to bindings.
Even if it were true that symbols and packages were more expressive than identifiers and lexicons (they aren't, but let's pretend for the sake of argument) this would still not follow. Expressiveness is not the only thing that people care about in their programming languages. Other things people care about include readability, debuggability, changeability, and conformance with whatever they consider to be the principles of good software engineering, and their intuitive expectations and prior knowledge. When all that is taken into account, it is far from clear that packages would be a win *even if* they provided superior expressiveness (which they don't).
> Any suggestion for solving the problem that favors > the latter over the former is a loser.
That depends on what you mean by "favors" and "loser". CL is the only extant language with symbols and packages. Even Scheme doesn't have symbols. (Scheme symbols aren't really symbols at all, they are just identifiers.) For a CL programmer to say that anything that deprecates packages is a loser is sort of like an Amish person saying that anything that deprecates horse-drawn buggies is a loser. By the Amish quality metric, it's true. But reasonable people can and do disagree.
> Lisp, and especially Common Lisp, is about making complex problems > easier to solve, not about making easy problems easy to solve. Packages > are in line with that.
Again, this depends on what you mean by "complex problem." There is nothing that I would consider a "complex problem" today for which either packages or lexicons provide a significant lever. This is a purely academic issue as far as I can tell.
> In article<9qakhoFju...@mid.individual.net>,
> Pascal Costanza<p...@p-cos.net> wrote:
>> On 18/02/2012 21:38, RG wrote:
>>> Whether that is a criticism of packages or the reader or something else
>>> is in the eye of the beholder, and in any case quite beside the point.
>>> The point is: there's a problem. Reasonable people can disagree over
>>> how serious this problem is or what (if anything) should be done about
>>> it. But that there is a problem is undeniable. (Note that "there is no
>>> problem" and "there is no problem FOR ME" are not equivalent statements.)
>> Yes, there is a problem. However, the concept of mapping strings to
>> symbols is in general more expressive,
> No, it isn't.
Yes, it is. See my posting from this afternoon.
>> and hence superior to mapping symbols to bindings.
> Even if it were true that symbols and packages were more expressive than
> identifiers and lexicons (they aren't, but let's pretend for the sake of
> argument) this would still not follow. Expressiveness is not the only
> thing that people care about in their programming languages. Other
> things people care about include readability, debuggability,
> changeability, and conformance with whatever they consider to be the
> principles of good software engineering, and their intuitive
> expectations and prior knowledge. When all that is taken into account,
> it is far from clear that packages would be a win *even if* they
> provided superior expressiveness (which they don't).
It's perfectly clear that packages are a win, even when taking all these issues into account. The problems are acknowledged, but the benefits outweigh them.
>> Any suggestion for solving the problem that favors
>> the latter over the former is a loser.
> That depends on what you mean by "favors" and "loser". CL is the only
> extant language with symbols and packages. Even Scheme doesn't have
> symbols. (Scheme symbols aren't really symbols at all, they are just
> identifiers.) For a CL programmer to say that anything that deprecates
> packages is a loser is sort of like an Amish person saying that anything
> that deprecates horse-drawn buggies is a loser. By the Amish quality
> metric, it's true. But reasonable people can and do disagree.
Sure, they disagree. But they are wrong.
>> Lisp, and especially Common Lisp, is about making complex problems
>> easier to solve, not about making easy problems easy to solve. Packages
>> are in line with that.
> Again, this depends on what you mean by "complex problem." There is
> nothing that I would consider a "complex problem" today for which either
> packages or lexicons provide a significant lever. This is a purely
> academic issue as far as I can tell.
Naming conflicts are a real issue in other languages. This is not just an academic problem.
>> 2) The Common Lisp package system virtually removes hygiene issues from
>> its macro system. The package system gives you a good way to precisely
>> specify which symbols are known outside of a macro and which are not.
> This may be a bit off the thread.
> I usually don't write anaphoric macros (not intentionally anyway :) )
> But I have one macro in my unit test system that goes like this
If you really want to go anaphoric, use a more distinctive name than just 'e, and make it possible to replace the default name with one's own name (by making 'error-var &optional, for example). Otherwise, you can get into trouble when you want to nest uses of your macros.
> On 18/02/2012 23:35, RG wrote:
> > In article<9qakhoFju...@mid.individual.net>,
> > Pascal Costanza<p...@p-cos.net> wrote:
> >> On 18/02/2012 21:38, RG wrote:
> >>> Whether that is a criticism of packages or the reader or something else
> >>> is in the eye of the beholder, and in any case quite beside the point.
> >>> The point is: there's a problem. Reasonable people can disagree over
> >>> how serious this problem is or what (if anything) should be done about
> >>> it. But that there is a problem is undeniable. (Note that "there is no
> >>> problem" and "there is no problem FOR ME" are not equivalent statements.)
> >> Yes, there is a problem. However, the concept of mapping strings to
> >> symbols is in general more expressive,
> > No, it isn't.
> Yes, it is. See my posting from this afternoon.
"This afternoon" is not a well defined concept on the internet.
But even if I could figure out which post you meant it wouldn't matter.
If you claim to have discovered an even prime greater than 2 it is not necessary for me to examine the details of your argument to know that you are wrong. I have already explained to you how lexicons can be made isomorphic to packages, so it cannot possibly be the case that packages are more expressive than lexicons. Anything you can do with a package, I can do with a lexicon.
There are two things that people commonly think you need packages for, and that is macros and slot value names. These people are wrong.
Coincidentally (or is that ironically?) the person who solved the problem of how to do hygienic macros in Common Lisp without packages is also named Pascal Costanza.
On 2012-02-18, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2012-02-18 00:15:41 +0000, RG said:
>> Well, bully for you. I use the REPL. I like the REPL. I get a lot of
>> leverage from the REPL. IMHO the REPL is one of the things that makes
>> Lisp better than, say, Java. And I don't think I'm the only one who
>> feels this way.
> strongly agree with that. I live in a REPL for weeks.
I'm afraid that I don't have the confidence that whatever is working
in the REPL's image will still work if I suddenly do a clean rebuild of the
system from whatever I have on disk (even if I reloaded all those materials
into the REPL).
How can you be sure that something you typed in three days ago isn't what is
making some test cases work?
I do all serious work from the basic principle of having a clean build
from properly versioned sources, all the time.
In article <20120218212338....@kylheku.com>,
Kaz Kylheku <k...@kylheku.com> wrote:
> On 2012-02-18, Tim Bradshaw <t...@tfeb.org> wrote:
> > On 2012-02-18 00:15:41 +0000, RG said:
> >> Well, bully for you. I use the REPL. I like the REPL. I get a lot of
> >> leverage from the REPL. IMHO the REPL is one of the things that makes
> >> Lisp better than, say, Java. And I don't think I'm the only one who
> >> feels this way.
> > strongly agree with that. I live in a REPL for weeks.
> I'm afraid that I don't have the confidence that whatever is working
> in the REPL's image will still work if I suddenly do a clean rebuild of the
> system from whatever I have on disk (even if I reloaded all those materials
> into the REPL).
Neither do I. The REPL is tremendously useful nonetheless.
> How can you be sure that something you typed in three days ago isn't what is
> making some test cases work?
You can't be sure. The REPL is tremendously useful nonetheless.
> I do all serious work from the basic principle of having a clean build
> from properly versioned sources, all the time.
Bully for you. That does not change the fact that some people find value in the REPL and manage to make it suit their needs despite its limitations and lack of theoretical purity.
BTW, nowadays most serious work involves interacting with systems and/or datasets which you do not control, and managing large quantities of state outside of the source code of your application. So unless you are working on a (by modern standards) trivial application, you can't be sure of anything even if you do start from a clean build before each run. And yet, people somehow manage to build things that work.
> In article <20120218212338....@kylheku.com>,
> Kaz Kylheku <k...@kylheku.com> wrote:
>> On 2012-02-18, Tim Bradshaw <t...@tfeb.org> wrote:
>> > On 2012-02-18 00:15:41 +0000, RG said:
>> >> Well, bully for you. I use the REPL. I like the REPL. I get a lot of
>> >> leverage from the REPL. IMHO the REPL is one of the things that makes
>> >> Lisp better than, say, Java. And I don't think I'm the only one who
>> >> feels this way.
>> > strongly agree with that. I live in a REPL for weeks.
>> I'm afraid that I don't have the confidence that whatever is working
>> in the REPL's image will still work if I suddenly do a clean rebuild of the
>> system from whatever I have on disk (even if I reloaded all those materials
>> into the REPL).
> Neither do I. The REPL is tremendously useful nonetheless.
>> How can you be sure that something you typed in three days ago isn't what is
>> making some test cases work?
> You can't be sure. The REPL is tremendously useful nonetheless.
I'm not saying the REPL isn't useful, but rather that it's still tremendously
useful even if you kill the image and start a new one once in a while.
Staying in the REPL for two weeks is mildly obsessive.
I want to regularly take stock of what I have, build the image cleanly, and
/then/ pop into the (tremendously useful) REPL and see how some things are
behaving. (Languages in which you can't do that are crippled in that regard:
a point that you made earlier about Java, etc.)
If I soil something with a package misuse, who cares. Kill it, and re-start.
I'm not living in the age of 30-minute-reboot Lisp machine.
>> I do all serious work from the basic principle of having a clean build
>> from properly versioned sources, all the time.
> Bully for you. That does not change the fact that some people find > value in the REPL and manage to make it suit their needs despite its > limitations and lack of theoretical purity.
> BTW, nowadays most serious work involves interacting with systems and/or > datasets which you do not control, and managing large quantities of > state outside of the source code of your application. So unless you are > working on a (by modern standards) trivial application, you can't be > sure of anything even if you do start from a clean build before each > run. And yet, people somehow manage to build things that work.
Those that do will more often than not have a test bed stuffed with specific
test data that lets them execute repeatable test cases, and can be reset to a
known initial state before every cycle with a new load.
People manage to build a lot of stuff that doesn't work, too.
> On 2012-02-19, RG <rNOSPA...@flownet.com> wrote:
> > In article <20120218212338....@kylheku.com>,
> > Kaz Kylheku <k...@kylheku.com> wrote:
> >> On 2012-02-18, Tim Bradshaw <t...@tfeb.org> wrote:
> >> > On 2012-02-18 00:15:41 +0000, RG said:
> >> >> Well, bully for you. I use the REPL. I like the REPL. I get a lot of
> >> >> leverage from the REPL. IMHO the REPL is one of the things that makes
> >> >> Lisp better than, say, Java. And I don't think I'm the only one who
> >> >> feels this way.
> >> > strongly agree with that. I live in a REPL for weeks.
> >> I'm afraid that I don't have the confidence that whatever is working
> >> in the REPL's image will still work if I suddenly do a clean rebuild of > >> the
> >> system from whatever I have on disk (even if I reloaded all those > >> materials
> >> into the REPL).
> > Neither do I. The REPL is tremendously useful nonetheless.
> >> How can you be sure that something you typed in three days ago isn't what > >> is
> >> making some test cases work?
> > You can't be sure. The REPL is tremendously useful nonetheless.
> I'm not saying the REPL isn't useful
Oh? You sure fooled me:
> I generally do not not use REPLs. Even when experimenting with
> code, I put it into small files and load those.
If the REPL is useful, why don't you use it?
BTW, it's not just the REPL where package problems show up. I find having to maintain export lists extremely annoying. (It violates the DRY principle.) Having name collisions among symbols with no bindings that are only used as identifiers is also annoying. None of this is catastrophic of course, but why make your life harder than it needs to be?
> If I soil something with a package misuse, who cares. Kill it, and re-start.
> I'm not living in the age of 30-minute-reboot Lisp machine.
You are also apparently not working on a project that takes 30 minutes to warm up its cache of stored state. Such applications are not uncommon nowadays. The project I'm currently working on takes about 2-3 minutes to restart on a small test dataset.
On Sun, 19 Feb 2012 06:21:17 +0000, Kaz Kylheku wrote:
> I'm not saying the REPL isn't useful, but rather that it's still
> tremendously useful even if you kill the image and start a new one once
> in a while.
> Staying in the REPL for two weeks is mildly obsessive.
> I want to regularly take stock of what I have, build the image cleanly,
> and /then/ pop into the (tremendously useful) REPL and see how some
> things are behaving. (Languages in which you can't do that are crippled
> in that regard: a point that you made earlier about Java, etc.)
> If I soil something with a package misuse, who cares. Kill it, and
> re-start. I'm not living in the age of 30-minute-reboot Lisp machine.
Restarting is fairly simple and relatively costless per se, but that's
not the issue. For me the issue is reconstructing the state I had
before I killed the image, which can be relatively costly. I can of
course deal with this by saving that state externally when possible,
but dealing with that imposes an extra development burden, which I
would prefer to postpone to a later stage in a project.
Of course there are other reasons for restarting the image (for me the
most common is memory corruption error when [mis]using foreign
libraries), but the fewer of these reasons, the better. So I am
watching attempts to fix packages with interest, even though my
development style is similar to the one you described above: I prefer
to work in files and I rarely go to the REPL directly, I only use it
via SLIME.
> How can you be sure that something you typed in three days ago isn't what is
> making some test cases work?
That's easy: If I'm developing software I want to keep: I have a big
powerful computer and I have a background job which cranks up a
noninteractive Lisp, does a cold build of the system and runs all its tests
every few minutes.
(This isn't meant to sound as sarcastic as it does sound, sorry)
> > How can you be sure that something you typed in three days ago isn't what is
> > making some test cases work?
> That's easy: If I'm developing software I want to keep: I have a big
> powerful computer and I have a background job which cranks up a
> noninteractive Lisp, does a cold build of the system and runs all its tests
> every few minutes.
> (This isn't meant to sound as sarcastic as it does sound, sorry)
My development process very rarely involves typing directly at the REPL.
Usually I have one REPL window and an editor window (sometimes a stack of editor windows). I'll edit something in the editor and hit ENTER, which causes the current sexpr to be sent to the listener (I use CCL).
The listener window keeps a transcript of everything I've done, and the editor window always has the latest version of the code. When I'm working this way, the compile-run overhead can be very close to zero, and it is not unusual for me to do multiple code iterations in under a minute despite the fact that I'm not a very fast typer.
When I have something working to the point where I think it's ready to commit, I re-evaluate the whole editor window and check to make sure it is still working. Then -- and only then -- do I fire up another Lisp image and re-load everything. It's pretty rare for something to fail at that point, and it's usually a macro that ended up being defined after it's invoked, which is usually obvious and fast to fix.
I've been working this way since 1985, when CCL stood for Coral Common Lisp instead of Clozure Common Lisp. It was then and remains to this day by far the best development environment I have ever used, bar none.