most modern FTP servers do this, which is a boon for people who use _real_ FTP clients, compared to the losers who use "browsers" and can only get what they see.¹
That doesn't say much for people who use ange-ftp or efs.
* Johan Kullstam <joha...@idt.net> | i now get franz-lisp-mode when i visit a file with a .l (for *l*isp) | ending. first it cursed about me not having rsh. i installed rsh and it | made eli happy to fire off a slave lisp process. (i don't use rsh for | anything else, can i remove the dependency on it?)
it is probably not a good idea to retain the franz-lisp mode in Franz Inc.'s ELI, but I'm not sure here. there is no "Franz Lisp", anymore that I know of, and the stuff that applies to its files are different from that which applies to Common Lisp and Allegro CL. so I took out the franz-lisp-mode stuff in my local version.
for Allegro CL, the canonical Lisp file type is "lisp" or "cl". lots of things become needlessly harder if you don't use either of these.
| i can pop between source editor and slaved lisp process with C-c l. C-c | C-b compiles. so far so good. i can type in the little function | examples from grahams books and try them out in the lisp slave. is this | how you do it in general?
I compile forms with C-M-x all the time, look at the value of special variables with C-u C-c C-s, request arglists with C-c a, macroexpand with C-c m, describe symbols with C-c d, and most usefully jump to definitions with C-c . and list callers with C-c c. I also use fi:edit-who-calls (bound to C-c e) when I change the signature of a function. all very useful stuff. I also use the :edit top-level command a lot, and even use the ED function to edit files with logical pathnames, since Emacs doesn't (yet) interface to Allegro CL in that way.
| i am still a bit stumped about how the process is supposed to work.
I find it hard to explain. the way I use Allegro CL is a function of what I have discovered that I can do. I fire up a number of listeners as the need arises and basically leave the Initial Lisp Listener alone (the trace output from Lisp processes go there, so it gets really cluttered if I try to do anything useful while tracing something).
| using make and command line compile commands and getting a normal unix | executable as with C or fortran doesn't seem to be the right thing with | lisp.
that's right. however, if you view the Unix way a little differently, it's actually a _subset_ of the way you do it in Lisp. with Unix, you edit a file, invoke some function to make its definitions available in your environment, then invoke the function you just defined. Unix stores its functions in files, while Lisp stores them in memory. either way, you invoke them basically the same way: you give each command loop a form to evaluate (the parentheses are implied in Unix, and you get a PROGN wrapper for free if you use the ; syntax). (the first word is even the name of the function. prefix syntax rules!)
the functions you invoke are just a little different between the two otherwise quite similar modes of operation. take "foo.c" and "bar.cl". you would invoke the compiler on "foo".c and get "foo". you would invoke COMPILE-FILE on "bar.cl" (or use FI:COMPILE-AND-LOAD-FILE directly from the buffer, which can conveniently be bound to the same key you bound M-x compile to in other modes). Lisp needs you to LOAD the file if you hadn't already done that. Allegro CL comes with three top-level commands that can save you some typing. :cf (compile-file), :ld (load), and :cl (compile-and-load), and all abbreviated with wild abandon, just like Unix tools. they also remember what you did last. (I think they should have had the same memory, though.)
Unix `make' is convenient in that it has a bunch of predefined ways to compile a number of files, and the Makefile is a nice place to store variable settings. if you want to make use the DEFSYSTEM facility in Allegro CL, you'll find that the defaults are less elaborate and you might need to say something like
then you'd say (compile-system :foo) or (load-system :foo :compile t) or the like, and things are taken care of. (it would have be nice if the top-level loop had had commands like :cs and :ls, but when I take the time to figure out how to make top-level commands, I'll post something.)
all in all, I think of Unix depriving me of the conveniences, and being rather limited in functions that have to do everything to remember their previous state themselves, but, really, a Unix command is no different from calling a Lisp function:
Lisp: (foo "x" 14 :mumble t :frotz nil)
GNU style: foo --mumble --no-frotz x 14
Unix style: foo -m -n x 14
the conveniences in Unix (like `make') are there because the lack of them would be inconvenient. that's how it usually goes with conveniences. to see how that would work in a language that doesn't have those particular conveniences, step back a little and think of what you'd do without them: you'd call the C compiler yourself on the particular file, and specify the output file. the conveniences of `make' is that it compiles only if needed and you don't need to tell it any file types. unsurprisingly, that's what the :cl command does in Allegro CL. the command :cl foo looks for a file foo.cl (or foo.lisp), sees if it is newer than the foo.fasl (or similar) file, compiles it if necessary, then loads it. and just as `make' takes a list of files to make something from, :cl takes a list of files to compile and load.
another bonus with LOAD-SYSTEM, by the way, is that it only loads the files it needs to load, so you don't run initializatio code unless you need to. the same applies to forms you compile with C-M-x: they are compiled in the same environment they are expected to run: with all the other functions and variables loaded. obviously, it works best to start off your work session by loading the last working version of your code. both LOAD (:ld) and LOAD-SYSTEM default to loading compile files rather than source files, so you're "safe" in that regard, too.
I hope this helps. I don't know any people who use Allegro CL exactly the same way, and what works for me may not even be useful advice for others. and remember: nothing beats reading the manual.
#:Erik -- if people came with documentation, could men get the womanual?
David Steuber <trash...@david-steuber.com> wrote: > I just downloaded ACL 4.3 For Linux from www.franz.com. I haven't > unpacked and installed it yet. I have some concerns about the license > that bother me. I was wondering if someone from Franz could clear > them up for me.
Why not download the 5.0 package? The one I got was still in beta (about 6 months ago). If it's been released to final, they might be sending demo CD's like they did with version 4.
Sunil Mishra <smis...@whizzy.cc.gatech.edu> writes: > One of my friends in usability pointed out that in some study, about the > only visual tool that turned out to be generally accepted as useful was > syntax highlighting.
how about indentation? that's visual. i think it's extremely useful. perhaps it's simply taken for granted.
> I personally have become so used to it that being > without it would make me far less productive. At least until I readapt. I > have practically given up on editing lisp programs over a vt100 terminal, > and find MCL inconvenient because I can't find a facility that does syntax > highlighting. (I did find one, but it inserted font codes into the text > document, which was not acceptable.)
i find unindented lisp code to be largely incomprehesible. C, C++ benefits greatly from good indention and even fortran can be made easier to read.
Johan Kullstam <joha...@idt.net> writes: > Sunil Mishra <smis...@whizzy.cc.gatech.edu> writes: > > One of my friends in usability pointed out that in some study, about the > > only visual tool that turned out to be generally accepted as useful was > > syntax highlighting.
> how about indentation? that's visual. i think it's extremely > useful. perhaps it's simply taken for granted.
I'm not arguing against the usefulness of indentation. But indentation along with coloring works even better. At least for me, colors allow me to quickly identify the location of various special constructs, such as defun and conditionals, and keywords that are often used, for example, in argument lists. Indentation good. Color good. Indentation + color even better.
In article <ug19rc99c....@res.raytheon.com>, Johan Kullstam <joha...@idt.net> wrote:
>Sunil Mishra <smis...@whizzy.cc.gatech.edu> writes: >> One of my friends in usability pointed out that in some study, about the >> only visual tool that turned out to be generally accepted as useful was >> syntax highlighting.
>how about indentation? that's visual. i think it's extremely >useful. perhaps it's simply taken for granted.
Ted Turner and his ilk colorize movies. That doesn't make them any "better". Just more accepted. (by the masses that is. Personally I think they are horrible. Especially if the original photography director knew anything about black and white photography. )
Perhaps the operative word here is "accepted". Where "accepted" means the user "likes" colored/highlighted syntax more. That doesn't neccesarily transfer into a large productivity gain ( other than happy readers are probably slightly more productive readers. ) Given unindented colorized code and uncolored indented code, I'd bet you'd be hard pressed to deliver experimental results that the former is significantly more productive than the latter.
However, if you took a "poll" syntax highlight would probably occur higher on the "top ten" list.
To drop some Lisp into this thread there was a reference to a Steele talk about "growing a language". One benefit of Lisp was that you can add new "operations" that look just like the "primitives". I don't see the big win over highlighting the language function/macro invocations over the user defined ones. They both have the same "form" ( I would say syntax but there are nuances between macros). So coloring one and not the other draws a distinction that really doesn't seem to matter much, IMHO.
[ At best it seems a distinction between looking on the HyperSpec versus looking in the source code for documentation. In Common Lisp if the environment and user defined code both have doc strings this is moot. ]
Strings, constants, and comments I find useful in font lock mode. When not terminated properly (e.g., no close doublee quote on a string) on a the colors tend to get a screwed up. Sort of like the emacs's paren highlighting. Being able to quickly classify comments vs. code is useful when reading because they are different semantically. My personal "MY-IF" and the default "IF" aren't to the same significance.
However, since some users "accept" vi more than emacs this too will come down to personal choice. I would just be careful with "usuability" and "accept" used in the same context.
--
Lyman S. Taylor "I'm a Doctor! Not a commando." (ly...@cc.gatech.edu) The enhanced EMH Doctor in a ST:Voyager epidsode.
In article <3124350472579...@naggum.no>, Erik Naggum wrote: > then you'd say (compile-system :foo) or (load-system :foo :compile t) or > the like, and things are taken care of. (it would have be nice if the > top-level loop had had commands like :cs and :ls, but when I take the > time to figure out how to make top-level commands, I'll post something.)
Is my understanding right that the Lisp Machines have various kinds of listeners for purposes like this? Or is there one which works for normal language-oriented queries as well as for OS-level (:ls) things?
Someone proposed (in a thread I can't find anymore) that before writing high-level libraries like CLIM, this listener functionality should be written. Any information about how this should work? A common Lisp listener/file system listener/inspector/debugger for all the various Common Lisp implementations sounds like a useful and powerful thing to have.
Lyman S. Taylor wrote: >... > To drop some Lisp into this thread there was a reference to a Steele > talk about "growing a language". One benefit of Lisp was that you can > add new "operations" that look just like the "primitives". I don't see > the big win over highlighting the language function/macro invocations > over the user defined ones. They both have the same "form" ( I would > say syntax but there are nuances between macros). So coloring > one and not the other draws a distinction that really doesn't seem > to matter much, IMHO.
IMNSHO, I think there is a problem if there is in fact no distinction between basic control constructs over user-level application code.
This ability to extend the language is a double-edged sword. Unfortunately I believe that the net effect has been negative, in that way too much lisp code is not understandable, extendable, maintainable, or in many cases useable, by other than the people who wrote it. This particularly problematic for extended basic controls, e.g. cond-every (why not cond* ?? ;) or for total hack macros. e.g. (from my own code ;) (loop-for-each-segment ...)
Furthermore in many cases such macrology can requires a big set of not-so-efficient support machinery to even execute the layers of abstraction. e.g. CL-HTTP or CLIM..
In article <slrn7927gl.10i.david.lichteb...@lambda.dummy.de>, david.lichteb...@snafu.de (David Lichteblau) writes:
> In article <3124350472579...@naggum.no>, Erik Naggum wrote: >> then you'd say (compile-system :foo) or (load-system :foo :compile t) or >> the like, and things are taken care of. (it would have be nice if the >> top-level loop had had commands like :cs and :ls, but when I take the >> time to figure out how to make top-level commands, I'll post something.)
> Is my understanding right that the Lisp Machines have various kinds of > listeners for purposes like this? Or is there one which works for > normal language-oriented queries as well as for OS-level (:ls) things?
The command tables on Symbolics can be hierarchical, ie one command table can inherit commands from other command tables. So for my app, I can define just my few new commands and inherit all the other ones from some preexisting one.
The standard lisp listener has all of those commands in it's default command table. (If I remember correctly, you can specify the command table to use when creating a listener.) For instance, the lisp listener has :Show Directory built in. The nice thing about the LispM implementation, is it has command completion (using the space key!). So I type in ":sh di " and I get ":Show Directory :directory <default>?" Since the commands are built upon presentation types, the reader knows what type the argument is. So I can type in a directory name, or I can click on an valid pathname displayed anywhere on the screen. And since Lisp knows the type of everything, when the results are displayed on the screen, the LispM remembers that info. So after I do the :Show Directory command, all of the pathnames printed out are mouse sensitive. The default action (left mouse click) for files is to execute ":Show File" with that pathname as the arg. For directories, it's too call ":Show Directory" with the pathname. The middle button is typically bound to ":Describe Object". The right button pops up a menu with several choices of things you can do to that object. For files, one of the choices is to edit the file, for instance. For object slots, one of the choices is to modify the slot. This gives a pretty complete "inspector" for free.
> Someone proposed (in a thread I can't find anymore) that before writing > high-level libraries like CLIM, this listener functionality should be > written. Any information about how this should work? A common Lisp > listener/file system listener/inspector/debugger for all the various > Common Lisp implementations sounds like a useful and powerful thing to > have.
> David
Actually, I think I proposed just the opposite. You really need CLIM to write the lisp listener. CLIM provides the framework for PRESENT and ACCEPT, and command tables upon with a listener would be built. Here's where efforts are currently at: http://www.mikemac.com/mikemac/McCLIM/index.html (Still got a ways to go for alpha release!)
* david.lichteb...@snafu.de (David Lichteblau) | Is my understanding right that the Lisp Machines have various kinds of | listeners for purposes like this?
I believe that's part of the package.
| Or is there one which works for normal language-oriented queries as well | as for OS-level (:ls) things?
:LS is ordinarily a Common Lisp keyword, but when the normal Allegro CL top-level read-eval-print loop reads a line that starts with the value of TOP-LEVEL:*COMMAND-CHAR* (ordinarily #\:), it is interpreted as a top-level command instead of an s-expression. however, these commands are _not_ "OS-level". :ls was intended to be an abbreviation just like :cf for COMPILE-FILE, :cl for COMPILE-AND-LOAD, etc, intended to mean LOAD-SYSTEM.
In article <slrn7927gl.10i.david.lichteb...@lambda.dummy.de>, david.lichteb...@snafu.de (David Lichteblau) wrote:
> In article <3124350472579...@naggum.no>, Erik Naggum wrote: > > then you'd say (compile-system :foo) or (load-system :foo :compile t) or > > the like, and things are taken care of. (it would have be nice if the > > top-level loop had had commands like :cs and :ls, but when I take the > > time to figure out how to make top-level commands, I'll post something.)
> Is my understanding right that the Lisp Machines have various kinds of > listeners for purposes like this? Or is there one which works for > normal language-oriented queries as well as for OS-level (:ls) things?
The Lisp Listener accepts Lisp forms and commands. The interesting thing is the Command Loop substrate. You can have a command loop anywhere - in your own applications, too.
> Someone proposed (in a thread I can't find anymore) that before writing > high-level libraries like CLIM,
You need CLIM to write such a listener. CLIM has as one example a simple listener.
Essentially CLIM is the user interface substrate of the Symbolics Lisp Machine (Dynamic Windows) rewritten in CLOS to be portable. It lacks the applications, though.
In my little CLIM Lisp Listener extension one can say "Load System", Compile System, ... ;-)
up left: the Lisp Listener up right: browsing packages down left: web hierarchy with browsed with CL-HTTP (it doesn't make sense for a gif, but you get the idea) down right: inspecting a class, showing the subclasses
In article <36911ED5.6E5CA...@IntelliMarket.Com>, Kelly Murray <k...@IntelliMarket.Com> wrote:
>IMNSHO, I think there is a problem if there is in fact no distinction >between basic control constructs over user-level application code.
In the context of "worse is better" and the seemingly sound arguments for "growing" a language, it isn't the facility that is a problem. Unconstrained and undirected growth, "Urban sprawl", is the problem.
The "language addition" feature is a clean/simple solution and it works. To add additional infrastructure (or complicated restraints ) to make it always the contexually "correct" solution seems problematical.
>This ability to extend the language is a double-edged sword.
If I may borrow and adapt a phrase....
"Swords don't kill people. People kill people."
>in that way too much lisp code is not understandable, extendable, >maintainable, or in many cases useable, by other >than the people who wrote it.
Then perhaps more effort has to be put into making people better "swordsmen" than in constraining the language. [ Admittedly, there is no "silver bullet" in producing folks who don't write code of this ilk. ]
In solving problems you can either bring the problem domain down to the level of the programming language or bring the programming language up to the level of the problem domain. [ Most often you have to do a little of both.] In the latter case, maintenance is more problematical if the maintainer knows programming language, but not the domain. However, it seems likely that latter approach would have less problems with correctness. [ Maintainers who don't understand the problem domain seem like a landmine just waiting to be stepped on.]
Unfortunately, the same mechanisms for "growing" the language to up to meet the problem domain can be used by "seat of the pants" language designers. "The common lisp committee really should have included my favorite geegaw from the 'whiz-bang' language into the lisp." That often is an "abuse" of the abstraction/extentsion mechanisms.
Of course, "beauty" is in the eye of the beholder. There is a fine line between "bring lisp up to the problem domain" and "write a new programming language (perhaps resembling lisp) layered on top of lisp" to solve the problem with. The latter is fine it is it your objective to write a new general purpose language on top of lisp. However, each new problem doesn't deserve its own unique language.
I think that the cry of "if you don't like common lisp's syntax, just write your own" should not be outlined as a prominent feature. Down that path lies the "Dark side". :-)
Indiscriminate use of EVAL can also be "misused" in Common Lisp programs. I don't think most would like to do without it though. I tell students to be conservative in its use. Like the "Dark side of the Force", it is seductive.
I suspect there is lots of "bad" lisp code out there (gratitous use of EVAL, baroque control mechanisms, etc.). Hopefully those authored by me have dissappeard in oblivion. :-) However, this legacy code should be labeled as "bad" and/or baroque. More well formed examples should be held up as counter-examples.
In summary, I think the "invent a language/feature of the week" culture is more the root cause of the problem in this case than the ultra-malleability of Lisp.
--
Lyman S. Taylor "I'm a Doctor! Not a commando." (ly...@cc.gatech.edu) The enhanced EMH Doctor in a ST:Voyager epidsode.
In article <3124471148557...@naggum.no>, Erik Naggum wrote: > however, these commands > are _not_ "OS-level". :ls was intended to be an abbreviation just like > :cf for COMPILE-FILE, :cl for COMPILE-AND-LOAD, etc, intended to mean > LOAD-SYSTEM.
You are right--`:ls' looked so much like Unix `ls' that I managed to misunderstand your remark, although the lack of :load-system as a top-level command has occurred to me, too.
Below is a simple definition of :ls and :cs that seems to work, but has not yet been tested thoroughly. Comments or corrections are appreciated!
USER(2): :help ls
The `ls' command calls the function `load-system' on its arguments; keyword arguments are accepted. The optional first argument is the name of a system. If no arguments are given, the last argument to one of the top-level commands dealing with systems is used.
USER(3): :help cs
The `cs' command calls the function `compile-system' on its arguments; keyword arguments are accepted. The optional first argument is the name of a system. If no arguments are given, the last argument to one of the top-level commands dealing with systems is used.
USER(4): :ls ls: no previous system USER(5): :cs cs: no previous system USER(6): :ls :test-system ; Loading system: "TEST-SYSTEM". ; Source is newer than product for module: "test-system". ; Loading product for module: "test-system". ; Fast loading /home/david/cl/test-system.fasl USER(7): :cs ; Compiling system: "TEST-SYSTEM". ; Compiling module "test-system" because the product file is out of date. ;;; Compiling file ./test-system.lisp ;;; Writing fasl file /home/david/cl/test-system.fasl ;;; Fasl write complete ; Loading product for module: "test-system". ; Fast loading /home/david/cl/test-system.fasl USER(8): :ls ; Loading system: "TEST-SYSTEM". USER(9): :ls :test-system :reload t ; Loading system: "TEST-SYSTEM". ; Loading product for module: "test-system". ; Fast loading /home/david/cl/test-system.fasl USER(10):
David
-------- source follows ;;; define new top-level commands ;;; :ls (`LOAD-SYSTEM') and ;;; :cs (`COMPILE-SYSTEM') ;;; similar to :ld and :cl
;;; the commands remember their first argument to make successive invocations ;;; easier to type. Make sure that different listeners do not clobber ;;; each other's memory of the argument. (Remove this form if you always ;;; want to work with the same system in all listeners.)
(eval-when (:execute :load-toplevel :compile-toplevel) (defmacro define-system-command (name (&optional system &rest other-args) documentation &body body) "Defines a new top-level command NAME that takes the optional argument named SYSTEM (and other arguments if given) and executes the BODY. If no system is given to the command, it defaults to the last argument to one of the commands defined. A DOCUMENTATION string is required." ;; this is more work than really needed for only two commands, but ;; it's more generic this way. ACL's DEFSYSTEM is flexible enough to ;; make more commands likely. (let ((real-name (if (consp name) ;two possible forms: (first name) ;list of string and options name)) ;only string (system-supplied-p (gensym "SYSTEM-SUPPLIED-P"))) `(tpl:alias ,name (&optional (,system *system-command-last-arg* ,system-supplied-p) ,@other-args) ,(format nil "The `~A' command ~A. The optional first argument is the name of a system. If no arguments are given, the last argument to one of the top-level commands dealing with systems is used." real-name documentation) (declare (special *system-command-last-arg*)) (if (and (not ,system-supplied-p) (null *system-command-last-arg*)) (format t "~a: no previous system" ,real-name) (prog1 (locally ,@body) (setq *system-command-last-arg* ,system)))))))
(define-system-command "ls" (name &rest args) "calls the function `load-system' on its arguments; keyword arguments are accepted" (apply #'excl:load-system name args))
(define-system-command "cs" (name &rest args) "calls the function `compile-system' on its arguments; keyword arguments are accepted" (apply #'excl:compile-system name args))
;;; WARNING! These should work, but I couldn't test them yet.
#| (define-system-command "mkls" (name &rest args) "calls the function `operate-on-system' with the operation `load' and possible other arguments given to the command" (apply #'operate-on-system name 'load args))
(define-system-command "mkcs" (name &rest args) "calls the function `operate-on-system' with the operation `load' and possible other arguments given to the command" (apply #'operate-on-system name 'compile args))
(define-system-command "oos" (name &rest args) "calls the function `operate-on-system' with the arguments given to the command" (apply #'operate-on-system name args)) |# -------- end of source