J.B.
> I saw a (nice) book in a bookshop with all kinds of compilers on a CD and
> short explanations of the languages. It also had a LISP compiler (XLISP).
> Now the author said that in reality LISP was a functional language.
Lisp has strong roots in Functional Programming (-> lambda calculus)
and Functional Programming grow up with Lisp (witness the conferences
"Lisp and Functional Programming") for a long time.
Common Lisp **supports** Functional Programming. It does not
**enforce** you to use FP - it just supports it - but quite well.
Even the OOP-substrate in Common Lisp (-> CLOS) uses Generic
Functions rather than Message Passing.
Common Lisp is a multi-paradigm language. It directly supports
imperative, functional and object-oriented programming.
It does not enforce you to use these - you have to choose.
Other programming paradigms can be incorporated easily -
this is a part of the "Lisp culture".
XLisp is an interpreter.
> Now the author said that in reality LISP was a functional language.
> Now
> (1) Is the correct definition of functional programming that it does not
use
> assigment?
Generally, functional programming language should avoid side-effects at all
and allow use of high-order functions.
> (2) Do you see LISP as a functional language? (I suppose that even a
> functional langauge must become imperative to some extent, at least when
it
> does IO?
>
If you will not use side-effect constructions Lisp would be *almost*
functional language, but then you'd better use Scheme for that matter. As I
understand, in pure functional languages special mechanisms (monads ?) are
used to deal with side-effecting but neccessary things like I/O and
hash-tables.
--
Eugene
(concatenate 'string "viking" "@" "cit.org.by")
> If you will not use side-effect constructions Lisp would be *almost*
> functional language, but then you'd better use Scheme for that matter.
There is no reason to do that. Scheme is no less or more "functional"
than Common Lisp (other than Scheme having full continuations
and tail call elimination in the standard).
You're right, but Scheme is a bit more elegant at function composition.
((foo a b) c d) looks more natural than (funcall (foo a b) c d), though
essentially it's the same.
Other issue is that if you drop out all side-effecting features from CL, it
wouldn't be any better than Scheme without them :)
that's no more than syntactic artificial sweetener at best. while it may
look cute to the uninitiate, the decision not to have FUNCALL means you
can't actually make indirect functions calls, as in the following very
useful idiom to process a list of functions.
(mapcar #'funcall <list-of-functions> ...)
of course, any real Lisper knows how to teach Scheme to be smart about
this, too, but Scheme has to be taught just about _everything_:
(define funcall (lambda (function . args) (apply function args)))
Scheme should adopt a new syntax for APPLY: (function . args). I've
suggested it before, and it's weird tha they haven't adopted it: it would
be so much more _elegant_ when compared to the syntax of the lambda lists.
#:Erik
--
Attention Microsoft Shoppers! MS Monopoly Money 6.0 are now worthless.
> I saw a (nice) book in a bookshop with all kinds of compilers on a CD and
> short explanations of the languages. It also had a LISP compiler (XLISP).
> Now the author said that in reality LISP was a functional language.
> Now
> (1) Is the correct definition of functional programming that it does not use
> assigment?
That's called "referential transparency". It's associated with
functional languages, but depending on who you listen to, it is or
isn't neccessary.
To some, passing functions around as first-class objects makes a
language functional. Eg, with mapcar and its buddies in Lisp.
> (2) Do you see LISP as a functional language?
No, not really.
> (I suppose that even a
> functional langauge must become imperative to some extent, at least when it
> does IO?
Off topic, but no, the pure functional languages like Haskell use
monads for IO. Monads are a whole topic, but basically they describe
world-modifying actions instead of commanding them. I expect some
criticism from those who'd prefer to define monads in terms of unit,
join, etc, but after asking around and reading Wadler's papers et al,
I think that is the best short summary of monads.
--
Tom Breton, http://world.std.com/~tob
Not using "gh" since 1997. http://world.std.com/~tob/ugh-free.html
> You're right, but Scheme is a bit more elegant at function composition.
> ((foo a b) c d) looks more natural than (funcall (foo a b) c d), though
> essentially it's the same.
Actually it is the other way around, IMHO.
Common Lisp's notation is far better:
FUNCALL makes function calls explicit. Ever wanted to understand
Scheme code that looks like:
(bar ((foo 1 2) 534)
(bar (((((baz)))))
((foo 3 4) 333)))
It's a pain. It's far better to use funcall to invoke
functions that have been returned by some random code.
You then can see in your source code what happens.
Nested parentheses just don't give enough visual clue.
Again, Common Lisp scales.
Rainer Joswig, ISION Internet AG, Harburger Schlossstraße 1,
21079 Hamburg, Germany, Tel: +49 40 77175 226
Email: rainer...@ision.de , WWW: http://www.ision.de/
> Common Lisp is a multi-paradigm language. It directly supports
> imperative, functional and object-oriented programming.
> It does not enforce you to use these - you have to choose.
These comments aren't too specific to Eugene's or Rainer's messages, I
just insert them here.
There are a few 'factoids' that sometimes bothered me, but I may be
wrong.
- When asked about paradigms in Lisp, the answer is often a menu of
paradigms (functional, imperative and object-oriented), and they
_appear_ to suggest that you would have to choose any one of them.
Functional and imperative styles are mutually exclusive, but you may
_also_ use OOP with either of them. In this sense, OO-nes and
transparency are orthogonal.
- Suggestions also appear to list the available paradigms as if they
were somehow equivalent, or of the same value. Even though imperative
style is well supported in Lisp (it even has the equivalent of GOTO),
hopefully people consider it inferior to the functional style. (Of
course, local deviations like ones in elaborate macros are a different
story.) Even though Lisp gives support for imperative style, I would
say that Lisp is fundamentally a functional (albeit impure) language.
- Re Eugene's messages:
> If you will not use side-effect constructions Lisp would be *almost*
> functional language, but then you'd better use Scheme for that
> if you drop out all side-effecting features from CL, it wouldn't be
> any better than Scheme without them :)
First, it suggests that Scheme is a pure functional language, which it
isn't. Second, it assumes that functional programming in CL means
little more than what Lisp 1.5 in the fifties could do. Even though
class definitions have to be stored somewhere, it is perfectly possible
to use CLOS and retain functional programming with all of its benefits.
As for object persistence or I/O, even pure FL's have their constructs
(monads), which are stylistically close to techniques of impure
languages.
I am yet to see a CL application programmed in imperative style, or a
functional language with the power of CL (YMMV)- heck, you can even use
lazy evaluation techniques described in CLtL2!
Robert
> > (2) Do you see LISP as a functional language?
>
> No, not really.
It is not really true.
Robert
> - When asked about paradigms in Lisp, the answer is often a menu of
> paradigms (functional, imperative and object-oriented), and they
> _appear_ to suggest that you would have to choose any one of them.
> Functional and imperative styles are mutually exclusive, but you may
> _also_ use OOP with either of them. In this sense, OO-nes and
> transparency are orthogonal.
I personally think that these paradigms are somehow very
nice integrated in Common Lisp.
> - Suggestions also appear to list the available paradigms as if they
> were somehow equivalent, or of the same value.
This would need a closer look.
> Even though imperative
> style is well supported in Lisp (it even has the equivalent of GOTO),
> hopefully people consider it inferior to the functional style. (Of
> course, local deviations like ones in elaborate macros are a different
> story.) Even though Lisp gives support for imperative style, I would
> say that Lisp is fundamentally a functional (albeit impure) language.
One of the problems:
Common Lisp does not enforce tail call elimination. This
means that recursion often is of a limited *practical* value
due to stack size problems. You must use one of the
several loop constructs - loop via recursion is often
running into practical problems.
To illustrate this in Macintosh Common Lisp:
(defun foo (n)
(if (zerop n)
'done
(foo (1- n))))
(foo 100000)
> Error: Stack overflow on value stack.
> To globally increase stack space,
> increase *MINIMUM-STACK-OVERFLOW-SIZE*
> While executing: ZEROP
> Type Command-/ to continue, Command-. to abort.
> If continued: Continue with a larger stack
See the RestartsÅ menu item for further choices.
1 >
; a lower debug value means also: use tail call elimination
(proclaim '(optimize (debug 2)))
(defun foo (n)
(if (zerop n)
'done
(foo (1- n))))
(foo 100000)
->
DONE
> class definitions have to be stored somewhere, it is perfectly possible
> to use CLOS and retain functional programming with all of its benefits.
It is even used in real-world programs.
For example CLIM often uses immutable objects (-> no side effects).
> I am yet to see a CL application programmed in imperative style,
There are lots - really lots. Quite a few coming from older
Lisp dialects or as translations from other languages.
or a
> functional language with the power of CL (YMMV)- heck, you can even use
> lazy evaluation techniques described in CLtL2!
Which are macros that make use of imperative features.
In general I also think that providing a kind of Functional Programming
is an essential property of Common Lisp - very powerful!
--
Rainer Joswig, ISION Internet AG, Harburger Schlossstrasse 1,
Isn't one of the attractions of Lisp that it can do whatever the
programmer wants? If you firmly believe the imperative style to
always be inferior, fine - you can write pure functional programs.
Personally, I find that sometimes the best way to solve a problem is
with functional code, sometimes, with imperative, and usually with a
mix.
I am sure that this will change as I learn more, but even if at some
point I write purely functional code I hope I won't ever assume I know
all the answers, and make such sweeping statements... In fact, if I
really was convinced functional programming was the One True Way I think
I would prefer moving to a stricly functional language just to keep
myself away from temptation ;-) (OCaml and O'Haskell both look
interesting).
So, answering the original post - no, I don't see Lisp as a functional
programming language. I see it as a the best language I've found yet
(and I can imagine better) for programming as *I* want to program,
without being pushed into a particular style. If I had to call it
something I'd say it was a catholic programming language (in the
non-religious sense of the word - in the religious sense, would
assembler be the puritan language?)
Andrew
http://www.andrewcooke.free-online.co.uk/index.html
Sent via Deja.com http://www.deja.com/
Before you buy.
> Hmm... Along with Erik's example on mapping a list of functions that makes a
> point. I admit that I never done any serious Scheme programming, let alone
> purely functional, and my opinion was based mostly on impression.
> But after all, who will want to do pure FP in Lisp? IMHO it is more of a
> hypothetical situation.
We were writing around 15 kloc dense Scheme code for a web site
(http://www.milka.de -> http://cowsim.milka.de).
It makes heavy use of higher-order functions, functions
returning functions, etc. It's big fun to write code this way and
it makes code very modular.
Seems like we will do a lot more Scheme programming for this
application next year. :-)
Perhaps I wasn't clear there. "Scheme without them" was supposed to mean
"Scheme with side-effecting features thrown off", therefore I wasn't
implying that Scheme is a pure FP language.
Although I agree with your remark about object system.
Wow! A cow simulator! I always told that Lisp is great at simulation :)
Nice site overall: engenders an instant desire to print page out and
chew it :)
--
Eugene (on lunch)
Some pure languages (Clean, http://www.cs.kun.nl/~clean/) use linear
(or uniqueness) types. Evidently, in a pure language you can still
name states of mutable object:
file1 = fwritec 'a' file0
file2 = fwritec 'b' file1
When the state transitions form a linear graph
... --> file0 --> file1 --> file2 --> ...
destructive update doesn't compromise the declarative meaning of
the program.
(Monadic IO can be implemented on top of linear types.)
rthappe
Janos B.
Eugene Zaikonnikov <vik...@cit.org.by> schrieb in im Newsbeitrag:
3825904D...@cit.org.by...
> Sorry but this is a bit off topic. You should find out instead if it is an
> imperative cow or a functional cow...
We have three types of cows to choose from. ;-)
> I am not an expert so I cannot find
> out. The chocolate is imperative i.e. I have to buy it...
No, every week the one taking best care of his cow wins a
chocolate package. Actually, the functions that compute the
high scores are written in pure FP style and are a bit hairy. ;-)
[snippitty-do-dah]
>
> Some pure languages (Clean, http://www.cs.kun.nl/~clean/) use linear
> (or uniqueness) types. Evidently, in a pure language you can still
> name states of mutable object:
>
> file1 = fwritec 'a' file0
> file2 = fwritec 'b' file1
>
> When the state transitions form a linear graph
>
> ... --> file0 --> file1 --> file2 --> ...
>
> destructive update doesn't compromise the declarative meaning of
> the program.
Still off topic: Yes, and as you prolly know that has the problem that
you can do the graph wrong - use a state twice or something. Monads
in effect force the graph to be linear.
In the case of Clean, the type checker prevents you from doing wrong.
Fully annotated types can look mildly horrible, though.
rthappe
I cannot think of any situations in which this is useful. Could you
please give an example? Thanks in advance!
Tord
Event handlers in GUIs?
--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
well, Emacs Lisp calls them "hooks" -- lists of functions to call to
allow users to customize the behavior of internal functions.
(this is all you get for advance thanks. :)
> * Tord Kallqvist Romstad
> | I cannot think of any situations in which this is useful. Could you
> | please give an example?
>
> well, Emacs Lisp calls them "hooks" -- lists of functions to call to
> allow users to customize the behavior of internal functions.
hmmm. what you are talking about is mapc'ing funcall over a list
of symbols, right?
the Scheme "moral equivalent" (if we assume that a hook is a list
of symbols, not closures) would be:
(map (lambda (sym . args) (apply (eval sym) args))
<list-of-names> ...)
that's too easy, so I probably don't get something here ;(.
--mike, puzzled
--
Don't trust these UNIX people. They are all demons. They kill their
parents and fork children. I don't know how they could do this with
their balls cut off but they manage. -- anonymous
> I cannot think of any situations in which this is useful. Could you
> please give an example? Thanks in advance!
I have code that looks like:
(funcall (if multiprocessing-p #'process-run-function
#'funcall)
#'(lambda ()
...))
--tim
> In article <31508981...@naggum.no>, Erik Naggum wrote:
> >
> >(mapcar #'funcall <list-of-functions> ...)
>
> I cannot think of any situations in which this is useful. Could you
> please give an example? Thanks in advance!
Emacs-style hooks. Say gnus-article-display-hook is a list of functions.
Now, whenever an article is displayed, use the above idiom to
call each function in the list on the article. In this case, the
functions do things like highlight urls, hide headers, de-mime the message,
etc.
Or, lists of actions that you associate with an event in a user interface.
Say you've got a button "destroy world." When the user clicks the
button, you funcall all the functions in the destroy-world-function-list.
-matt
--
Eugene
indeed. the point is that you have to write your own FUNCALL by hand.
I also happen to do (apply #'funcall <list>) at times. I guess Scheme's
(apply (eval (car list)) (cdr list)) is much more _elegant_. hee hee!
I think the arguments for much of Scheme's purported elegance are really
stupid and it doesn't help when Schemers don't even recognize that they
are arguing against electronic gas lighters because they can make do with
their beautifully carved flint stones.
Thank you for answering, but there is still one thing I don't understand:
How do you pass the argument(s) to the functions in list-of-functions?
Tord
[Responding to Michael Livshin <cmm+...@verisity.com>]
As a matter of fact, it _is_ too easy, since EVAL takes two arguments (by
R5RS):
(map (lambda (sym . args)
(apply (eval sym (scheme-report-environment 5)) args))
<list-of-names>)
for example. In addition, it doesn't make any sense, since there is
nothing to which to bind ARGS, unless your <list-of-names> resembles
'(proc0 proc1 proc2 ...) '(arg00 arg10 arg20 ...) '(arg01 arg11 arg21 ...) ...
Of course, then the list of symbols representing procedures and the list
of arguments must be of the same length, which begs the question of just
what, exactly, you are trying to do?
As I've seen them, hooks are generally applied to arguments, with all
hooks receiving the same arguments, which in Scheme would likely resemble:
(for-each (make-run-hooks <hook-arguments>) <list-of-hooks>)
i.e.,
(for-each (make-run-hooks event window) *window-destroyed-hooks*)
where
(define make-run-hooks
(lambda args
(lambda (hook)
(apply hook args))))
Now, that's not so terrible, is it?
Erik Naggum <er...@naggum.no>:
>
> indeed. the point is that you have to write your own FUNCALL by hand.
>
> I also happen to do (apply #'funcall <list>) at times. I guess Scheme's
> (apply (eval (car list)) (cdr list)) is much more _elegant_. hee hee!
>
True, true. (apply #'funcall <list>) is quite a bit more elegant than the
latter; however, this is generally not the way work gets done in Scheme,
as you no doubt know. There is almost never any reason that one opts to
retain the symbol bound to a location containing a function over retaining
the function itself, especially when the CDR of the list contains EVAL'ed
arguments for the CAR of the list...I just don't get it. The above
inelegant Scheme form should just be:
(eval <list> <environment>)
Erik Naggum <er...@naggum.no>:
>
> I think the arguments for much of Scheme's purported elegance are really
> stupid and it doesn't help when Schemers don't even recognize that they
> are arguing against electronic gas lighters because they can make do with
> their beautifully carved flint stones.
>
I tend to agree with the sentiment that much of the elegance of Scheme is
due to the sparsity of the language; however, formulating arguments which
only prove that _you_ are capable of constructing a solution in Scheme,
which is extremely ugly in the face of the elegant Common Lisp solution,
really doesn't tell me very much about the Scheme _language_.
Chris.
--
Chris Kirkwood-Watts
kirk...@raytheon.com
Christophe Kirkwood-Watts 0790340 <kirk...@cna0790340.rsc.raytheon.com> writes:
> [Responding to Michael Livshin <cmm+...@verisity.com>]
>
> As a matter of fact, it _is_ too easy, since EVAL takes two arguments (by
> R5RS):
>
> (map (lambda (sym . args)
> (apply (eval sym (scheme-report-environment 5)) args))
> <list-of-names>)
well, I wasn't trying to be pedantic. note that in Scheme, you don't
usually store symbols that name functions, you store the functions
themselves (well, you do note that below). also, if I would store
symbols, I wouldn't look them up with eval, because that doesn't make
any sense. presumably I know the context in which I want the symbols
to name things, and I look them up in that context, by whatever means
are appropriate (hook-symbol->procedure or something).
> Of course, then the list of symbols representing procedures and the list
> of arguments must be of the same length, which begs the question of just
> what, exactly, you are trying to do?
sloppily illustrate an irrelevant point, as it turned out ;)
> Erik Naggum <er...@naggum.no>:
> >
> > I think the arguments for much of Scheme's purported elegance are really
> > stupid and it doesn't help when Schemers don't even recognize that they
> > are arguing against electronic gas lighters because they can make do with
> > their beautifully carved flint stones.
> >
>
> I tend to agree with the sentiment that much of the elegance of Scheme is
> due to the sparsity of the language; however, formulating arguments which
> only prove that _you_ are capable of constructing a solution in Scheme,
> which is extremely ugly in the face of the elegant Common Lisp solution,
> really doesn't tell me very much about the Scheme _language_.
at the risk of misunderstanding Erik (again), the point seems to be,
basically, that Common Lisp has this nice function called `funcall',
and Scheme doesn't. as well as an awful lot of other useful things.
> Chris.
--mike
--
newsgroup volume is a measure of discontent. -- Erik Naggum
(mapcar #'funcall '(+ - *) '(1 2 3) '(4 5 6))
This works, of course, but I thought matt meant that all the functions
in list-of-functions should be used on the same argument (in his example,
a news article). Having to construct a list of copies of this single
argument of the same length as the list of functions seems very inconvenient.
Tord
Tord Kallqvist Romstad <rom...@janus.uio.no> wrote in message
news:<slrn82h4rt....@janus.uio.no>...
In this situation, i would use something like:
(mapcar #'(lambda (next)
(funcall next my-arg)) list-of-functions)
No need for a list of copies of my-arg. This will apply your list of
functions, in turn, on the same argument and return a list containing the
results of each funcall.
Just curious now, if a function returns multiple values, i imagine you'll
only get the first? How would you get all the return values out of a
mapcar? (no particular purpose in mind, maybe this is something to avoid
even trying...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Coby Beck
Software Developer
__________________________
Mercury Scheduling Systems
400 - 601 West Cordova
Vancouver, BC, Canada
ph - (604) 683-8668 ext 370
fax- (604) 688-2375
http://www.mercury.bc.ca/
Email- cbeck at mercury.bc.ca
> Just curious now, if a function returns multiple values, i imagine you'll
> only get the first? How would you get all the return values out of a
> mapcar? (no particular purpose in mind, maybe this is something to avoid
> even trying...)
You don't get all the multiple values out of a mapcar.
Instead of (mapcar f stuff) you'd have to do something like
(mapcar (lambda (x) (multiple-value-list (funcall f x))) stuff)
(or you might prefer the results of MAPCAN).
This isn't something one often wants, though...
--
Gareth McCaughan Gareth.M...@pobox.com
sig under construction
You are certainly right (other than misquoting me), and most people use
a mixed style in Lisp. I use imperative features when it is either of
local effect, and I don't have to worry about its consequences beyond
the boundaries of the containing function, or is a means of implementing
(or meta-) levels of abstractions, e.g., via macros.
Although Lisp definitely supports imperative style, I think that using
special variables, destructive operations and side effects all over and
globally is an underutilization of Lisp's abstraction capabilities,
which does not scale well with problem complexity. I would guess your
programs are also more on the functional side.
Regards
Robert
I'd guess there is no way to avoid consing this way.
Here's an example from CLtL2 on using series functions with functions
returning multiple values:
(map-fn '(values integer rational)
#'floor #Z(1/4 9/5 12/3))
=> #Z(0 1 4) and #Z(1/4 4/5 0)
Robert
please get your attributions right. I'm taking a Schemer's proposed code
as a given. I make no representation to write elegant Scheme code. far
from it, I think Scheme is an _inelegant_ language the exact same way I
think anything else that is beautiful only when tiny and undeveloped
grows into huge morasses of disgustitude when actually put to real use,
like GUILE. it actually amazes me constantly that the elegance of Scheme
does not scale beyond the standard and the core language, but it's like
they say in biology: an insect is built the way it is because it is so
small, and an elephant the way it is because it is so big. both work
quite well with their body builds, while neither would work with the
others' body build even when scaled appropriately. design a language as
elegant and small as an insect, and it will collapse under its own weight
if it tries to grow big, but design a language able to grow big systems,
and it will necessarily look extremely bloated if scaled down to the
insect size that some people use to jugde languages and applications,
like the size of "hello, world" programs, to take the glaring example.
| I tend to agree with the sentiment that much of the elegance of Scheme is
| due to the sparsity of the language; however, formulating arguments which
| only prove that _you_ are capable of constructing a solution in Scheme,
| which is extremely ugly in the face of the elegant Common Lisp solution,
| really doesn't tell me very much about the Scheme _language_.
just you get your attributions right, mister, and this will all rectify
itself automatically. and check your blood pressure while you're at it.
I don't like Scheme, and I make no bones about it. if you don't like
that somebody thinks Scheme is ugly and the Scheme community silly for
its insistence on elegance through missing features, learn to live with.
it would indeed, so we don't. given this very useful function:
(defun circular-list (arg &rest args)
(let ((car (list arg)))
(nconc car args car)))
for a single argument, the answer is simply this:
(mapcar #'funcall <list-of-functions> (circular-list <arg>))
for a list of arguments, it gets just a _little_ hairier:
(apply #'mapcar #'funcall <list-of-functions>
(mapcar #'circular-list <arguments>))
but it's OK to be a little afraid of this code until you figure it out.
#:Erik :)
But since in Scheme the "function" position is evaluated with the *same*
rules as the "arg" positions -- that is, the function position can be
*any* expression that evaluates to a function -- you can accomplish the
above in Scheme with:
((if multiprocessing-p process-run-function (lambda (x) (x)))
(lambda ()
...))
-Rob
p.s. A definition of "funcall" that would work with the above *and*
handle the more general uses of "funcall" is:
(define (funcall f . rest) (apply f rest))
Then you could say:
((if multiprocessing-p process-run-function funcall)
(lambda ()
...))
-----
Rob Warnock, 8L-846 rp...@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
1600 Amphitheatre Pkwy. FAX: 650-933-0511
Mountain View, CA 94043 PP-ASEL-IA
What you didn't get [and thereby triggered an otherwise needless flamefest
from Erik! ;-} ;-} ] is that the "Scheme moral equivalent" is *NOT* a
"list of symbols", but (as you *almost* said) "a list of closures" themselves.
So no "eval" is needed at all:
(for-each (lambda (x) (x)) *foo-hook*)
or if there are per-function-dependent args to be passed:
> (map (lambda (f a1 a2) (f a1 a2))
(list + - * /) ; "list", not "quote": get the the *values*!
'(1 2 3 4)
'(5 6 7 8))
(6 -4 21 1/2)
>
Or more generally, using the more general definition of Scheme "funcall"
I gave in another reply in this thread:
> (define (funcall f . rest) (apply f rest))
> (map funcall (list + - * /)
'(1 2 3 4)
'(5 6 7 8)
'(0.1 0.1 0.1 0.1))
(6.1 -4.1 2.1 5.0)
>
Scheme and Common Lisp have *very* different "natural" styles in some areas,
and the "Lisp1" nature of Scheme and the fact that the function position
of a call is evaluated *exactly* the same way as the argument positions
means that in most situations where a Common Lisp programmer might pass
around the *name* of a function -- knowing that "symbol-function" is cheap
and does not require "eval" -- the Scheme programmer will simply pass around
the function itself.
Unlike Erik [whose opinion I respect], I do like Scheme... for some things.
But I definitely have learned that Scheme is *not* a "subset" or even
"dialect" of Common Lisp (though my opinion, which various others agree
*and* disagree with, is that Scheme is certainly a member of the generic
"Lisp family"), and that it is best not to try to argue detailed comparisons
between them (other than maybe presenting rough crib sheets for use by
people trying to move from one to the other, for whatever reason).
-Rob
> What you didn't get [and thereby triggered an otherwise needless flamefest
> from Erik! ;-} ;-} ] is that the "Scheme moral equivalent" is *NOT* a
> "list of symbols", but (as you *almost* said) "a list of closures" themselves.
> So no "eval" is needed at all:
>
> Scheme and Common Lisp have *very* different "natural" styles in some areas,
> and the "Lisp1" nature of Scheme and the fact that the function position
> of a call is evaluated *exactly* the same way as the argument positions
> means that in most situations where a Common Lisp programmer might pass
> around the *name* of a function -- knowing that "symbol-function" is cheap
> and does not require "eval" -- the Scheme programmer will simply pass around
> the function itself.
*cough* The "_modern_Lisp_ moral equivalent" is to pass closures, not global
function names.
--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1 email: matomira AT acm DOT org
CH-2007 Neuchatel tel: +41 (32) 720-5157
Switzerland FAX: +41 (32) 720-5720
www.csem.ch www.vrai.com ligwww.epfl.ch/matomira.html
> Tim Bradshaw <t...@tfeb.org> wrote:
> +---------------
> | * Tord Kallqvist Romstad wrote:
> | > I cannot think of any situations in which this is useful. Could you
> | > please give an example? Thanks in advance!
> |
> | I have code that looks like:
> | (funcall (if multiprocessing-p #'process-run-function #'funcall)
> | #'(lambda ()
> | ...))
> +---------------
>
> But since in Scheme the "function" position is evaluated with the *same*
> rules as the "arg" positions -- that is, the function position can be
> *any* expression that evaluates to a function -- you can accomplish the
> above in Scheme with:
>
> ((if multiprocessing-p process-run-function (lambda (x) (x)))
> (lambda ()
> ...))
If multiprocessing is on then 'process-run-function' executes the
lambda, otherwise the lambda is sipmply returned as a value.
> p.s. A definition of "funcall" that would work with the above *and*
> handle the more general uses of "funcall" is:
>
> (define (funcall f . rest) (apply f rest))
>
> Then you could say:
>
> ((if multiprocessing-p process-run-function funcall)
> (lambda ()
> ...))
Now, this would work.
Cheers
> *cough* The "_modern_Lisp_ moral equivalent" is to pass closures, not global
> function names.
I thought there was just a whole thread about how this was actually a
bad thing to do sometimes:
(cons #'foo *hooks*)
(defun foo ()
;; oops
...)
--tim
[snip]
> I think Scheme is an _inelegant_ language the exact same way I
> think anything else that is beautiful only when tiny and undeveloped
> grows into huge morasses of disgustitude when actually put to real use,
> like GUILE. it actually amazes me constantly that the elegance of Scheme
> does not scale beyond the standard and the core language, but it's like
Have you had a chance to look at the SRFIs (Scheme Requests For
Implementation <http://srfi.schemers.org/>)? I'd be interested in
whether you think the scaling problem holds there. The whole SRFI
processs seems to be the first, general, community based attempt to
expand the scope of (portable) Scheme. (I think certain particular
Scheme implementations have done fairly well at adding a higher level,
but "elegant" superstructure onto core Scheme (EdScheme comes to mind
and maybe Bigloo? RScheme is rather nice too; of course, they're
incompatible!)
A more general possible counterexample is Smalltalk. The core language
(syntax and semantics) is very simple (simpler than Scheme's, I'd say),
but a large, nicely elegant system was built with it (the prime example
being the general Smalltalk-80 system).
(Of course, I'm not entirely sure what the property is that would cause
disgustitude. In a formal system, there's generally a tradeoff between
simplicity of the base/primative concepts and simplicity of representing
interesting ones. Just because all the logical particles of the first
order predicate calculas can be replaced with Sheffer stroke doesn't
mean you'd want to write anything as simple as '(A & B) -> B' using
nothing be Sheffer strokes.)
Cheers,
Bijan Parsia.
> Have you had a chance to look at the SRFIs (Scheme Requests For
> Implementation <http://srfi.schemers.org/>)? I'd be interested in
> whether you think the scaling problem holds there.
To chime in without being asked (this is not an answer anyway):
There has been a significant progress in Scheme (referring to SRFI's and
the Guile Object-Oriented Language), and tt seems Scheme is slowly but
surely getting closer to where Common Lisp is. It is clearly
beneficial, as it allows people write more and more code efficiently (in
terms of run-time and development time) and portably.
On the other hand, you recognize that it adds to language size and
complexity, which is not a problem, as these things are often being done
now in one implementation or another, and tools that scale well with
problems are usually a bit more complex than ones where tool size
minimalism matters more.
I'm sure that there are lots of legacy stuff in Common Lisp. As I have
only been using lisp for a few years, and I have never had to deal with
legacy code, I for sure must be someone who is be pissed off by legacy
considerations, and I must have been open to Lisp and Scheme equally.
Indeed, I had to be more open towards Scheme, because it's a toolset
easier to learn in its completeness.
I found myself, however, preferring CL more and more for its maturity,
completeness and portability. Although I have sometimes been terrified
with what I do not know about CL, I gained confidence step by step in
that eventually I would be able to use all CL facilities, and I can
manage now without knowing everything.
The reason I preferred maturity, completeness and portability over
language simplicity is not only the availability of commercial
implementations, but also the fact that I need it as a tool that I can
rely on, rather than a draft (no pun intended) I need to work on myself
(yes, I consider myself a user of the language rather than an
implementor - of course, I would not even think about aspiring to be a
language _designer_, when there is so much more to catch up with in
Common Lisp).
I'd like to illustrate my point with a simple example. For quite some
time, I did not occur to me why APPLY can take multiple arguments plus a
rest argument. It didn't bother me enough to think, read or ask about
it. When I wanted to pass on arguments through multiple function calls
with the ability to use some of them, but simply passing on other
keyword arguments blindly until they reach their destination, I got
enlightened about the simple, yet powerful approach, and I could only
feel grateful for people who put in so much work, thought and practical
experience into the design of this language, and that it was readily
available when I needed it.
Also, while legacy may bother people, I just found myself not being
reliant on them. I guess some lispers of much longer experience than
mine consider CLOS nothing more than an abstraction layer built on
structures and other things (as the first OO implementations sometimes
were), but I instead consider structures to be but a simplified, dumbed
down CLOS, and in fact I don't even use them. I never used the CL
facility to print a number in English, but its existence has never hurt
me - maybe it comes handy one day.
So to reverse the question you asked: don't you think Scheme (or maybe
even Java to a lesser extent) eventually finds its way towards being
comparable to CL* (both in size and features), but you have to carry the
burden of ever-evolving and growing Scheme interpreters/compilers?
Aren't you spending quite some time already designing and implementing
new Scheme features, looking up CL specifications for inspiration and
juggling Scheme environments? In the meantime, I always _use_ the
language when I start a CL environment.
Bijan, please don't think I have always been biased - I was simply being
practical, fond of powerful and clean abstractions. These are not
rhetorical questions. Relative to the history of Scheme and CL, I am a
newcomer, open-minded about making my choice of language for the time
horizons that matter to me. I'm also prone to go my way and
re-innovate, but I have often find it unproductive.
Also, not everybody is bound to _Scheme_ by legacy, and I'm sure people
who understand the trend and significance of Scheme's evolution are also
willing to base decisions not just on (their) Scheme legacy but on a
fresh, serious look at Common Lisp.
Regards
Robert
* People having doubts about Scheme playing catch-up with CL should
indeed go to http://srfi.schemers.org to see things like string library,
multiple values, exceptions (OK, not conditions) and dynamic scoping.
Also, OO and macro facilities are more similar to those of CL than
RxRS. (I think that the term "portable and yet useful code" is somewhat
unfortunate, but indicative of the current state of Scheme.)
You're not reading what I typed clsoely enough. What you said would have
be true if I had typed *this*:
((if multiprocessing-p process-run-function (lambda (x) x))
(lambda ()
...))
but I didn't. In what I typed (which you quoted correctly), if
multiprocessing is on the lambda on the following lines is passed
as a parameter to the "process-run-function", otherwise the lambda
is passed as a parameter to the unnamed function "(lambda (x) (x))",
which *calls* it! (...with no args.) Again:
(lambda (x) (x)) ; calls its arg
(lambda (x) x) ; returns its arg
+---------------
| > p.s. A definition of "funcall" that would work with the above *and*
| > handle the more general uses of "funcall" is:
| > (define (funcall f . rest) (apply f rest))
| > Then you could say:
| >
| > ((if multiprocessing-p process-run-function funcall)
| > (lambda ()
| > ...))
|
| Now, this would work.
+---------------
Both forms work as originally posted.
Exactly. CL gives you the *choice* of binding lateness versus effeciency,
because "symbol-function" is in the language standard and is relatively
cheap, compared to "eval". I didn't mean to imply that CL *couldn't* pass
closures, or that it wasn't usually "the right thing", but only that
Scheme-the-standard doesn't give you a *choice* other than (presumably slow)
"eval", so passing closures is usually considered the "only right thing".
Having said that, of course, someone will chide me about how specific
*implementations* of Scheme give you "(global-defined-value <symbol>)"
[which, for Scheme, a Lisp-1, is the closest equivalent of "symbol-function"
and presumably as cheap] or the like, but I think we're talking mostly
about the standard-defined languages here, yes? Implementation extensions
don't count in such discussions.
-Rob
p.s. Due credit: "global-defined-value" is from MzScheme
hi
this makes me so curious. how csn one implement GOTO in lisp?
]hopefully people consider it inferior to the functional style. (Of
]course, local deviations like ones in elaborate macros are a different
]story.) Even though Lisp gives support for imperative style, I would
]say that Lisp is fundamentally a functional (albeit impure) language.
]
]- Re Eugene's messages:
]
]> If you will not use side-effect constructions Lisp would be *almost*
]> functional language, but then you'd better use Scheme for that
]
]> if you drop out all side-effecting features from CL, it wouldn't be
]> any better than Scheme without them :)
]
]First, it suggests that Scheme is a pure functional language, which it
]isn't. Second, it assumes that functional programming in CL means
]little more than what Lisp 1.5 in the fifties could do. Even though
]class definitions have to be stored somewhere, it is perfectly possible
]to use CLOS and retain functional programming with all of its benefits.
]As for object persistence or I/O, even pure FL's have their constructs
](monads), which are stylistically close to techniques of impure
]languages.
]
]I am yet to see a CL application programmed in imperative style, or a
]functional language with the power of CL (YMMV)- heck, you can even use
]lazy evaluation techniques described in CLtL2!
]
]Robert
]
]
--Deepak
elegantly. :) see TAGBODY and GO. a number of forms are implicit
TAGBODYs the same way a number of other forms are implicit PROGNs.
#:Erik
> [...]
> hi
>
> this makes me so curious. how csn one implement GOTO in lisp?
>
> [...]
Do you know about the GO special operator? If so, are you asking
about its implementation?
--
Samir Barjoud
sa...@mindspring.com
On 11 Nov 1999, Samir Barjoud wrote:
]
]
--Deepak
> Erik Naggum <er...@naggum.no> wrote:
>
> [snip]
>
> > I think Scheme is an _inelegant_ language the exact same way I
> > think anything else that is beautiful only when tiny and undeveloped
> > grows into huge morasses of disgustitude when actually put to real use,
> > like GUILE. it actually amazes me constantly that the elegance of Scheme
> > does not scale beyond the standard and the core language, but it's like
>
> Have you had a chance to look at the SRFIs (Scheme Requests For
> Implementation <http://srfi.schemers.org/>)? I'd be interested in
> whether you think the scaling problem holds there. The whole SRFI
> processs seems to be the first, general, community based attempt to
> expand the scope of (portable) Scheme.
The SRFI process is a good thing and I would advocate a similar one
for CL. But, let's consider what are the current SRFI for Scheme,
let's say SRFI Final 8: "RECEIVE: Binding to multiple values". Or
SRFI 12: "Exception Handling", or, again, SRFI 13: "String Library".
Do we see a pattern here? Or maybe it easier to see what is missing? :)
In other words, there is a way to "expand the scope of (portable) Scheme":
use CL. :)
[...]
Rob> Exactly. CL gives you the *choice* of binding lateness versus
Rob> effeciency, because "symbol-function" is in the language
Rob> standard and is relatively cheap, compared to "eval". I didn't
Rob> mean to imply that CL *couldn't* pass closures, or that it
Rob> wasn't usually "the right thing", but only that
Rob> Scheme-the-standard doesn't give you a *choice* other than
Rob> (presumably slow) "eval", so passing closures is usually
Rob> considered the "only right thing".
I don't understand why must we use eval.
Rob> Having said that, of course, someone will chide me about how
Rob> specific *implementations* of Scheme give you
Rob> "(global-defined-value <symbol>)" [which, for Scheme, a Lisp-1,
Rob> is the closest equivalent of "symbol-function" and presumably as
Rob> cheap] or the like, but I think we're talking mostly about the
Rob> standard-defined languages here, yes? Implementation extensions
Rob> don't count in such discussions.
What's the problem with this approach?
;;Defining func1
(define func1 (list (lambda () (display "do something") (newline))))
;;Defining func2
(define func2 (list (lambda () (display "do more things") (newline))))
;;Running hooks extracts the function before applying it
(define (run-hooks hooks)
(for-each (lambda (hook)
((car hook)))
hooks))
;;Let's create some hooks
(define my-hooks (list func1 func2))
;;Let's run them
> (run-hooks my-hooks)
do something
do more things
;;Let's redefine func1
(set-car! func1 (lambda () (display "I'm not doing the same thing") (newline)))
;;Let's run the hooks again
> (run-hooks my-hooks)
I'm not doing the same thing
do more things
Why do we need a specific *implementation* of scheme? It doesn't seem
hard to define some macrology to hide the explicit use of list and
set-car!.
It doesn't seem to me that car and set-car! are less efficient than
symbol-function and (setf symbol-function).
Maybe I don't understand the problem...
António Leitão.
Because the original problem being discussed was hooks that are lists
of *symbols*, as is often done in Emacs & CL, not closures. That is:
(define my-hooks (list 'func1 'func2))
Now, if (for better or worse) that's how the hook is *defined*, how
do you call those functions in *standard* Scheme without using "eval"?
[...or a non-standard extension such as MzScheme's "global-defined-value".]
+---------------
| What's the problem with this approach?
...
| (define my-hooks (list func1 func2))
...
| (define (run-hooks hooks)
| (for-each (lambda (hook) ((car hook))) hooks))
+---------------
[Uh... You don't need the "car"; "for-each" does that for you.]
Well, your hook variable is a list of *closures*, not symbols.
That certainly "works" (for some definitions of "work"), but fails
to address two of the issues others expressed in this thread:
(1) that the traditional Lisp hook style is to use symbols, and
(2) that using symbols instead of closures has the advantage of
automatically using the *new* value of any hook function that's
redefined, even *after* being added to the hook. Compare both ways:
> (define (foo) (print "foo"))
> (define (bar) (print "bar"))
> (define sym-hook (list 'foo 'bar)) ; the symbol-based version
> (define (do-sym-hooks)
(for-each (lambda (x) ((eval x))) sym-hook))
> (define clo-hook (list foo bar)) ; the closure-based version
> (define (do-clo-hooks)
(for-each (lambda (x) (x)) clo-hook))
> (do-sym-hooks)
foo
bar
> (do-clo-hooks)
foo
bar
>
The same so far, yes? Now look what happens when we redefine one
of the hook functions:
> (define (foo) (print "this is a new, improved foo!!"))
> (do-sym-hooks)
this is a new, improved foo!!
bar
> (do-clo-hooks)
foo
bar
>
Oops!!
-Rob
p.s. Yes, there are ways to get around this problem *without* using
"eval", e.g., make every hook function be a trampoline for the "real"
function, the one that gets edited:
> (define (real-foo) (print "foo"))
> (define (foo) (real-foo))
> (define clo-hook (list foo bar))
> (do-clo-hooks)
foo
bar
> (define (real-foo) (print "this is a new, improved foo!!"))
> (do-clo-hooks)
this is a new, improved foo!!
bar
>
But 'tis a bit cumbersome, yes?
> Well, your hook variable is a list of *closures*, not symbols.
> That certainly "works" (for some definitions of "work"), but fails
> to address two of the issues others expressed in this thread:
> (1) that the traditional Lisp hook style is to use symbols, and
> (2) that using symbols instead of closures has the advantage of
> automatically using the *new* value of any hook function that's
> redefined, even *after* being added to the hook. Compare both ways:
No, I think his hook var is a list of lists, the car of each list being a
function/closure, so (because you can clobber the car of the list),
some kind of redefinition would work. But it wouldn't be the kind you
get in CL -- redefine the function, and the new one gets called, you'd
need a special macro or something to do this. Which is kind of what
CL people are complaining about -- in Scheme you need to do everything
yourself!
--tim
Rob> Antonio Leitao <a...@gia.ist.utl.pt> wrote:
Rob> +---------------
Rob> | >>>>> "Rob" =3D=3D Rob Warnock <rp...@rigden.engr.sgi.com> writes:
Rob> | Rob> Scheme-the-standard doesn't give you a *choice* other than
Rob> | Rob> (presumably slow) "eval", so passing closures is usually
Rob> | Rob> considered the "only right thing".
Rob> |
Rob> | I don't understand why must we use eval.
Rob> +---------------
Rob> Because the original problem being discussed was hooks that are lists
Rob> of *symbols*, as is often done in Emacs & CL, not closures. That is:
Rob> (define my-hooks (list 'func1 'func2))
Rob> Now, if (for better or worse) that's how the hook is *defined*, how
Rob> do you call those functions in *standard* Scheme without using "eval"?
Rob> [...or a non-standard extension such as MzScheme's "global-defined-value".]
It's not that hard, actually. Just use an assoc-list (or hashtable)
that relates the symbol to the function. If that's the way you want
to define my-hooks, I would say that:
(define hook-function-table
(list (cons 'func1
(lambda () (display "do something") (newline)))
(cons 'func2
(lambda () (display "do more things") (newline)))))
and
(define (run-hooks hooks)
(for-each (lambda (hook)
((cdr (assq hook hook-function-table))))
hooks))
solves the problem.
Of course, we should define a macro such as
(def-hook (func1)
(display "do more things")
(newline))
that takes car of updating the hook-function-table. Again, it doesn't
look very hard.
You might argue that this approach is slower than using eval. You can
you hashtables, if you need the extra speed, but at least you have the
usual lexically scoped evaluation.
Rob> +---------------
Rob> | What's the problem with this approach?
Rob> ...
Rob> | (define my-hooks (list func1 func2))
Rob> ...
Rob> | (define (run-hooks hooks)
Rob> | (for-each (lambda (hook) ((car hook))) hooks))
Rob> +---------------
Rob> [Uh... You don't need the "car"; "for-each" does that for you.]
Are you sure? I don't think you can do that. For-each is applied to
a list of lists. Each of the lists contains just one function. Each
list is in fact an handle that allows me to change the function
dynamically. As a result, the lambda is applied to each of these
handles and must use car to extract the function.
Note that func1 was defined as:
(define func1 (list (lambda () (display "do something") (newline))))
Note the list around the lambda.
Rob> Well, your hook variable is a list of *closures*, not symbols.
Not quite.
My hook variable was (in the version you are mentioning) a list of
handles to closures. See above.
Rob> That certainly "works" (for some definitions of "work"), but fails
Rob> to address two of the issues others expressed in this thread:
Rob> (1) that the traditional Lisp hook style is to use symbols, and
I use symbols in the second version.
Rob> (2) that using symbols instead of closures has the advantage of
Rob> automatically using the *new* value of any hook function that's
Rob> redefined, even *after* being added to the hook. Compare both ways:
Again, you just need some macrology to hide the update (either to the
handle in the first version or to the assoc-list in the second version).
>> (define (foo) (print "foo"))
>> (define (bar) (print "bar"))
>> (define sym-hook (list 'foo 'bar)) ; the symbol-based version
>> (define (do-sym-hooks)
Rob> (for-each (lambda (x) ((eval x))) sym-hook))
>> (define clo-hook (list foo bar)) ; the closure-based version
That's not what I was doing...
>> (define (do-clo-hooks)
Rob> (for-each (lambda (x) (x)) clo-hook))
>> (do-sym-hooks)
Rob> foo
Rob> bar
>> (do-clo-hooks)
Rob> foo
Rob> bar
>>
It's obvious that this would not work. But if you look carefully to
my solution you will see that it's not what you are suggesting. Try
my solution.
Rob> The same so far, yes? Now look what happens when we redefine one
Rob> of the hook functions:
>> (define (foo) (print "this is a new, improved foo!!"))
>> (do-sym-hooks)
Rob> this is a new, improved foo!!
Rob> bar
>> (do-clo-hooks)
Rob> foo
Rob> bar
>>
Rob> Oops!!
Pretty obvious...
Look again at my previous solution, please.
Note that I'm not a Scheme fanatic (or CL fanatic, for that matter).
I just didn't understand what was so different in Scheme and CL that
would make impossible to do in Scheme something so simple as
implementing hooks.
Maybe I'm still not understanding the problem...
On the other hand, there are some things in Scheme that are extremely
difficult to implement in CL. As a result, I think that with some
extra SRFIs (maybe 20 more) Scheme will be similar to CL, (modulo
being a Lisp1) but with one added feature: first class continuations.
Rob> p.s. Yes, there are ways to get around this problem *without* using
Rob> "eval", e.g., make every hook function be a trampoline for the "real"
Rob> function, the one that gets edited:
>> (define (real-foo) (print "foo"))
>> (define (foo) (real-foo))
>> (define clo-hook (list foo bar))
>> (do-clo-hooks)
Rob> foo
Rob> bar
>> (define (real-foo) (print "this is a new, improved foo!!"))
>> (do-clo-hooks)
Rob> this is a new, improved foo!!
Rob> bar
>>
Rob> But 'tis a bit cumbersome, yes?
I agree. I prefer my solutions.
António.
Which did I get wrong? I have re-examined my post and the postings
previous in this thread, and I am unable to locate the error.
>
> I'm taking a Schemer's proposed code as a given. I make no
> representation to write elegant Scheme code.
>
The code to which I can only assume you refer is reproduced below. Notice
that it is _not_ what the "Schemer" wrote, nor does it perform the same
action. Consequently, I can only conclude that either you made it up, or
you yourself are the source the attribution error.
Erik Naggum <er...@naggum.no>:
>
> I also happen to do (apply #'funcall <list>) at times. I guess Scheme's
> (apply (eval (car list)) (cdr list)) is much more _elegant_. hee hee!
>
As far as the rest of the post is concerned, please realize that you are
arguing against no one.
>
> Scheme is an _inelegant_ language the exact same way I think anything
> else that is beautiful only when tiny and undeveloped grows into huge
> morasses of disgustitude when actually put to real use, like GUILE.
>
[...]
>
> just you get your attributions right, mister, and this will all rectify
> itself automatically. and check your blood pressure while you're at it.
> I don't like Scheme, and I make no bones about it. if you don't like
> that somebody thinks Scheme is ugly and the Scheme community silly for
> its insistence on elegance through missing features, learn to live with.
>
I regret that it was inferred that my hostility was directed towards you
on account of your attitude towards Scheme. I am well aware of this
attitude, and I respect your opinions. It was, however, the opportunistic
and mindless Scheme-bashing which simply did not seem warranted in this
case, since the catalyst of the tirade was Scheme code that you personally
constructed.
Chris.
--
Chris Kirkwood-Watts 972/5756402
kirk...@raytheon.com
I like code which scares me, I can usually learn a lot from it (unless it
is scary because it is badly written, of course). After some thought,
I understand how this code works, but I am not at all sure I would be
able to invent this idea myself. Thank you for sharing this idea with me!
:-)
Tord
(defun circular-list (arg &rest args)
(let ((car (list arg)))
(nconc car (copy-list args) car)))
as the standard spec on &rest args (3.4.1.3 A specifier for a rest parameter)
explicitly allows: The value of a rest parameter is permitted, but not
required, to share structure with the last argument to apply.
I don't know if this is a problem with any actual current implementation, though.
Bernhard
--
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for http://www.ai.univie.ac.at/~bernhard/
Artificial Intelligence bern...@ai.univie.ac.at
What exactly are "first-class continuations" in Scheme? Semantically,
Scheme and Common Lisp's LAMBDA expressions are identical (modulo an
explicit FUNCALL in CL to get around it's Lisp-2-ness), so I assume
your talking about something other than closures in either language.
Are you talking about CALL-WITH-CURRENT-CONTINUATION in Scheme?
--
"I'm very busy. I'm preparing my next mistake." -- B. Brecht
Matthew> Antonio,
Matthew> What exactly are "first-class continuations" in Scheme?
Matthew> Semantically, Scheme and Common Lisp's LAMBDA expressions
Matthew> are identical (modulo an explicit FUNCALL in CL to get
Matthew> around it's Lisp-2-ness), so I assume your talking about
Matthew> something other than closures in either language. Are you
Matthew> talking about CALL-WITH-CURRENT-CONTINUATION in Scheme?
Precisely.
Antonio.
The right way to do this is not to use symbols but as follows:
(defglobal *hooks* ())
(defmacro add-hook (fn)
(if (symbolp fn)
;; add indirection to catch any redefinitions of fn
`(add-hook-fn #'(lambda () (,fn)))
;; otherwise assume it's an expression evaluating to a function object.
`(add-hook-fn ,fn)))
(defun add-hook-fn (fn)
(setq *hooks* (cons fn *hooks*)))
This avoids the evil symbol-function, which is evil in the same way as eval
is evil (i.e., it refers explicitly to the global environment and thus
interlaces programs too closely to the
development environment, making application delivery harder.)
-- Harley
> bpa...@email.unc.edu (Bijan Parsia) writes:
>
> > Erik Naggum <er...@naggum.no> wrote:
> >
> > [snip]
> >
> > > I think Scheme is an _inelegant_ language the exact same way I think
> > > anything else that is beautiful only when tiny and undeveloped grows
> > > into huge morasses of disgustitude when actually put to real use, like
> > > GUILE. it actually amazes me constantly that the elegance of Scheme
> > > does not scale beyond the standard and the core language, but it's
> > > like
[snip]
>
> The SRFI process is a good thing and I would advocate a similar one
> for CL. But, let's consider what are the current SRFI for Scheme,
> let's say SRFI Final 8: "RECEIVE: Binding to multiple values". Or
> SRFI 12: "Exception Handling", or, again, SRFI 13: "String Library".
>
> Do we see a pattern here? Or maybe it easier to see what is missing? :)
>
> In other words, there is a way to "expand the scope of (portable) Scheme":
> use CL. :)
:) Sure. And even when we have SRFI 1000, there will still be a number
very good reasons to use Common Lisp. No doubt whatsoever.
The point in question is whether Scheme can remain "elegant" (both in
the common judgement, and by its core community's lights) while scaling
up to the functionality of Common Lisp. In other words, when we hit SRFI
will we merely have a gigantic bug collapsing under it's own weight with
*really* hideous feelers aping the elegant trunk of an elephant? I.e.,
will we have Common Scheme or GUILE (in the way Erik described it) ;)
Of course, there are (at least) two ways Scheme could falter in this
scaling--it could turn really ugly and cumbersome, or it could depart
from the notion of elegance embodied in the standard and the core
language (i.e., as if one implemented Common Lisp on top of a Scheme
core). If the langauge you end up using isn't recognizably Scheme, then
what *was* the point of expanding it? (I'll contrast again with
Smalltalk...expanding Smalltalk doesn't require introducing entirely new
techniques or styles. The *feel* of programming remains pretty much the
same across the board.)
Cheers,
Bijan Parsia.
> Bijan Parsia wrote to Erik:
>
> > Have you had a chance to look at the SRFIs (Scheme Requests For
> > Implementation <http://srfi.schemers.org/>)? I'd be interested in
> > whether you think the scaling problem holds there.
>
> To chime in without being asked (this is not an answer anyway):
[snip]
> On the other hand, you recognize that it adds to language size and
> complexity, which is not a problem, as these things are often being done
> now in one implementation or another, and tools that scale well with
> problems are usually a bit more complex than ones where tool size
> minimalism matters more.
*Usually*, yes. Absolutely. I guess the real life question is what's the
(an) optimal tradeoff. (Aiya, yes, it's much more complex than this. I'm
really just wondering about Scheme and whether it is such that given
it's particular minimalism, the techniques one develops using the core
language--the lessons it teaches--just fail when applied to larger
domains. They problem isn't just *should* one standardize libraries, but
does adding the useful stuff make Scheme hideous? The difference between
the SRFI process and the stuff particular implementors have built is
that roughly the same folks who value (in all their different ways) the
Scheme standard, are working on, and commenting on, the SRFI. So they're
more nearly an expression of the same consuses values that produced the
standard. Thus, one would hope, SRFIs will generally have the same
properties as the standard. If it's an inherent feature of Scheme that
it can't scale without ugliness, *this* (and not, e.g., GUILE) is the
place to look.)
[snip]
> I found myself, however, preferring CL more and more for its maturity,
> completeness and portability.
Again, CL definitely has those virtues. In spades. But I think, and I'm
pretty sure Erik thinks, that CL has it's own (kind of?) elegance. And
that's a reason to like and use it. Even if Scheme with SRFI 1-1000
provides all the functionality of CL *and* does so in a "schemely
elegant" way, there will, I wager, be reasons to prefer the Common Lispy
elegant way.
(That the current standard may not full exemplify the platonic idea of
CL elegance is, naturally, no proper strike against it. It certainly is
the current *best* exemplar it, and a rather decent exemplar it is.)
[snip]
> So to reverse the question you asked: don't you think Scheme (or maybe
> even Java to a lesser extent) eventually finds its way towards being
> comparable to CL* (both in size and features), but you have to carry the
> burden of ever-evolving and growing Scheme interpreters/compilers?
Huh? The extant CL implementations are every-evolving and growing as
well, as is good.
> Aren't you spending quite some time already designing and implementing
> new Scheme features, looking up CL specifications for inspiration and
> juggling Scheme environments? In the meantime, I always _use_ the
> language when I start a CL environment.
Even if true, I don't quite see the point. I can perfectly well grant
that CL is more mature and stable (which I do) without granting that
Schemely elegance can't scale to CL scope. Which is what I'm curious
about. Common Lisp has hard evidence that it can handle big problems
well. Scheme, whilst remaining Schemely, hasn't yet proven that. If it
can, then there's more choice for people who might find they prefer a
Schemely style.
[snip]
> Relative to the history of Scheme and CL, I am a
> newcomer, open-minded about making my choice of language for the time
> horizons that matter to me. I'm also prone to go my way and
> re-innovate, but I have often find it unproductive.
Sure. I'm not sure why your telling *me* this. I'm not a programmer, nor
do I do much more than *study* Scheme and CL (but I do study both). When
I do program, I tend to program in Smalltalk, which bears some
resemblance to Scheme (small core) and CL (lots of functionality, scales
well to big problems). (This is *not* to say, imply, suggest, whatever
that Smalltalk is Better than CL or Scheme; I just offer it as an
existence proof that minimal initial toolset needn't fail to scale. If
Scheme can't scale, I suspect that it's something *else* about the
minimalism. But I don't know that it can't scale. One example of, IMHO,
a unpleasant "beefed up" Scheme is DrScheme. Bleah. Of course, part of
their problem is the UI toolkit they use for cross-platform support
(wxWindows) which is horrible, horrible.)
[snip]
You've really lost me. I'm not arguing for Scheme over Common Lisp, or
Common Lisp over Scheme. Nor am I trying to entice anyone. So all this
stuff is irrelevant.
Cheers,
Bijan Parsia.
Indeed. The symbol-function approach is OK, I
guess, for .emacs customization and such, but that it
is not available as immediately in Scheme as in CL is
not a big loss.
--d
Is there a concise discussion of the problem of application delivery in
Lisp somewhere? What other functions make this more difficult?
--
Kenneth P. Turvey <kt-...@SprocketShop.com>
--------------------------------------------
Over himself, over his own body and mind, the individual is sovereign.
-- John Stuart Mill
My ex-ILOG Talk colleagues and I wrote a paper about this subject for the
ACM Lisp and Functional Programming Conference in 1994 ("Talking about
Modules and Delivery," by Davis, Parquier, and Seniak), where we discuss the
interlacing of the compilation and execution environments common in most
Lisp implementations and how we avoided it in the ILOG Talk module system,
whose explicit goal was simplifying the delivery of applications.
-- Harley
> Thus, one would hope, SRFIs will generally have the same
> properties as the standard.
As one of the defining qualities of the standard is minimalism, this is
difficult to expect.
> Again, CL definitely has those virtues. In spades. But I think, and I'm
> pretty sure Erik thinks, that CL has it's own (kind of?) elegance.
I haven't said CL is not elegant, I just haven't based my argument on
CL's elegance.
> And
> that's a reason to like and use it. Even if Scheme with SRFI 1-1000
> provides all the functionality of CL *and* does so in a "schemely
> elegant" way, there will, I wager, be reasons to prefer the Common Lispy
> elegant way.
Absolutely.
[arguments on Scheme growth and instability from me]
> Huh? The extant CL implementations are every-evolving and growing as
> well, as is good.
Yes, but please note that fundamental and substantial (useful)
applications from many years ago are still capable of running. There
has always been a remarkable stability in the CL world, and the key is
that the standard has covered enough ground to allow useful
applications. Even non-standard features like multiprocessing are more
similar across implementations than the wild variety of object systems
for Scheme.
> I can perfectly well grant
> that CL is more mature and stable (which I do) without granting that
> Schemely elegance can't scale to CL scope. Which is what I'm curious
> about. Common Lisp has hard evidence that it can handle big problems
> well. Scheme, whilst remaining Schemely, hasn't yet proven that. If it
> can, then there's more choice for people who might find they prefer a
> Schemely style.
It seems to me that much of Scheme's style stems from its minimalism.
Reading both c.l.l. and c.l.s., I am yet to see a convincing example for
Schemely style. The examples that came up (e.g., avoiding funcall or
macro hygiene) could be trivially done in CL with short macros. Maybe
you have got something specific in mind?
[snip]
> Sure. I'm not sure why your telling *me* this. I'm not a programmer,
It is difficult to define who you call a programmer. By the way, I am
not sure why you are telling *me* you are not a programmer :-)
> When
> I do program,
Alright, I have assumed you are a Scheme programmer because of the
contents of your posting and the fact that this was about the first time
I saw your name on c.l.l.
Regards
Robert
Sent via Deja.com http://www.deja.com/
Before you buy.
> The papers are here :-
> ftp://ftp.ilog.fr/pub/PostScript/Talk/
Now here's something that actually didn't make it into the Lisp
implementation lists:
ftp://ftp.ilog.fr/pub/Products/Talk/
--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1 email: matomira AT acm DOT org
CH-2007 Neuchatel tel: +41 (32) 720-5157
Switzerland FAX: +41 (32) 720-5720
www.csem.ch www.vrai.com ligwww.epfl.ch/matomira.html
Yes, there is a linux version in there, but it hasnt been updated
wrt to libc issues for a long while. The last version of linux I had
it working with was RH 5.2. It might still work with the libc5
compatibility stuff tough really I think it needs rebuilding now and
some changes to the emacs lisp code (It had a great emacs interface,
especially the stepper).
Jon
> some changes to the emacs lisp code (It had a great emacs interface,
> especially the stepper).
Breakpoints were cool indeed.
> The right way to do this is not to use symbols but as follows:
>
> (defglobal *hooks* ())
>
> (defmacro add-hook (fn)
> (if (symbolp fn)
> ;; add indirection to catch any redefinitions of fn
> `(add-hook-fn #'(lambda () (,fn)))
> ;; otherwise assume it's an expression evaluating to a function object.
> `(add-hook-fn ,fn)))
>
> (defun add-hook-fn (fn)
> (setq *hooks* (cons fn *hooks*)))
>
> This avoids the evil symbol-function, which is evil in the same way as eval
> is evil (i.e., it refers explicitly to the global environment and thus
> interlaces programs too closely to the
> development environment, making application delivery harder.)
Harley,
I can see an advantage to your approach, namely that it handles
refs to both global and local functions in a uniform way. And a
compiler (or whatever) can tell what function you're referring to,
something not revealed by the symbol-function approach. So your
approach may well be better for application delivery.
However, I don't agree that symbol-function has a pernicious
connection with the development environment. A Lisp with no
development environment could still have symbol-function.
-- jd
Hi Jeff,
The point with symbol-function (like eval) is that you cannot statically
analyze a program to determine its full set of references. So you can't
easily determine what the delivered application can refer to at runtime, and
therefore minimize the size of the application. Instead, you need to make
the user explicitly state what the runtime components of the app are, or do
some heuristic method like tree-shaking. These methods are unsound since
people can make mistakes and tree-shaking may not cover all necessary edge
cases.
Other functions, like "load-file", also share this problem but
symbol-function is less obvious in its implications to a naive user.
The connection between symbol-function (& co.) and the development
environment is twofold: First, everything you need is almost certainly
going to be there during development, but the only way to guarantee that
same completeness at delivery (modulo the pragma or heuristic methods
mentioned above) is to ship the development environment itself. Second, the
delivered application needs to maintain whatever indirections are present in
the development environmnet for the app to continue working, and this may
lead to some loss of efficiency since some indirections (such as going
through a symbol for function calling) can be compiled away if the compiler
can guarantee that no function redefinition or other runtime-access to the
symbol's function cell is required.
Naturally, a Lisp with no development environment could also have
symbol-function; the connection is empirical rather than theoretical. (A
Lisp could also have a development environment and no programmer-accessible
symbol-function - that's pretty much what you get with C++ w/o RTTI.)
Common Lisp is not really geared towards minimal application delivery
because of symbol-function and other similar constructs (and esp. due to the
lack of any serious standard module/library system), but the problem is, I
believe, worth considering for future Lisp dialects, as we considered it for
EuLisp and Ilog Talk, for instance.
-- Harley
> Common Lisp is not really geared towards minimal application delivery
> because of symbol-function and other similar constructs (and esp. due to the
> lack of any serious standard module/library system), but the problem is, I
> believe, worth considering for future Lisp dialects, as we considered it for
> EuLisp and Ilog Talk, for instance.
Ditto Dylan.
Dylan has symbols but these are lightweight interned strings and have no other
values or properties associated with them. There is no language-level way to
call a function through a name in Dylan -- the application would have to build
that association itself.
For the terminally interested, simple hook functionality could be implemented
as follows in Dylan:
define variable *hooks* = make(<stretchy-vector>);
define method add-hook (fn :: <function>)
add!(*hooks*, fn);
end method;
define method run-hooks ()
do(method (f) f() end, *hooks*); // note lack of funcall! :-j
end method;
Given this lack of automatic symbolic association in Dylan it was thought that
the internal hook-like module inside Functional Developer (nee Harlequin
Dylan) should actually allow clients to distinguish between hook identity and
hook callback if they want to.
__Jason
> On Mon, 15 Nov 1999 13:29:00 -0800, "Harley Davis"
> <nospam...@nospam.museprime.com> wrote:
> > Common Lisp is not really geared towards minimal application delivery
> > because of symbol-function and other similar constructs [...]
> [...]
> Dylan has symbols but these are lightweight interned strings and
> have no other values or properties associated with them.
Nothing stops symbols from being just as lightweight in Common Lisp.
The various items (value cell, plist, etc) associated with Symbols in
Common Lisp do not have to be part of the symbol structure, and so
they don't have to take up significant space for a symbol unless
someone actually assigns (setfs) to symbol-value, symbol-plist, or
whetever. The traditional implementation of symbols had all those
cells on the plist anyway.
And nothing stops a Common Lisp implementation from having some
way to declare that only functions that are called directly can
also be called via the corresponding symbol.
So the existence of symbol-function need not be a very serious
problem for implementations that wish to be geared towards minimal
applications delivery.
-- jd
> Jeff Dalton <je...@todday.aiai.ed.ac.uk> wrote in message
> news:x2bt8vh...@todday.aiai.ed.ac.uk...
> > Harley,
> > I can see an advantage to your approach, namely that it handles
> > refs to both global and local functions in a uniform way. And a
> > compiler (or whatever) can tell what function you're referring to,
> > something not revealed by the symbol-function approach. So your
> > approach may well be better for application delivery.
> > However, I don't agree that symbol-function has a pernicious
> > connection with the development environment. A Lisp with no
> > development environment could still have symbol-function.
> Hi Jeff,
Hi Harley, how are things in the Lispless wilderness? (Not that I
actually know what museprime does.)
> The point with symbol-function (like eval) is that you cannot statically
> analyze a program to determine its full set of references.
Yes, the "compiler (or whatever) [cannot] tell what function you're
referring to".
> So you can't
> easily determine what the delivered application can refer to at runtime, and
> therefore minimize the size of the application. Instead, you need to make
> the user explicitly state what the runtime components of the app are, or do
> some heuristic method like tree-shaking. These methods are unsound since
> people can make mistakes and tree-shaking may not cover all necessary edge
> cases.
Of course, people can make mistakes; but that's true anyway. If
the user's code maintains its own mapping from symbols to functions
(as someone suggests might be done in Dylan), some functions might
be left out.
Anyway, a Common Lisp implementation could have a way for to declare
that static analysis limits what what can be called via symbol
function. (I assume that's not what you meant by "expliticly stating
what the runtime components are"; and it's static analysis, not a
heuristic. So it doesn't sound like too bad a solution.)
> The connection between symbol-function (& co.) and the development
> environment is twofold: First, everything you need is almost certainly
> going to be there during development, but the only way to guarantee that
> same completeness at delivery (modulo the pragma or heuristic methods
> mentioned above) is to ship the development environment itself.
There may be a problem with having certain kinds of development
environments (though I don't think the case is all that strong),
but you seemed to think symbol-function was a source of evil in
itself. I don't think it is.
> Second, the
> delivered application needs to maintain whatever indirections are present in
> the development environmnet for the app to continue working, and this may
> lead to some loss of efficiency since some indirections (such as going
> through a symbol for function calling) can be compiled away if the compiler
> can guarantee that no function redefinition or other runtime-access to the
> symbol's function cell is required.
Lisp system have been dealing with the indirection problem for ages,
with various kinds of block compilation and declarations.
So the worst you're "empirical" connection seem to come down to,
in your two cases, is not that there has to be a significant problem
in practice, but that there's no *guarantee* that some things might not
be omitted or mistakenly declared. But in any case, the problems are
due to having a certain kind of development env, not to symbol-function.
And, at the end of the day, if people want all errors to be detected
at compile time, they're going to have a hard time writing any
interesting programs. If Common Lisp is too "dymanic" for some
purposes, implementations should be able to deal with it fairly well
without any need to eliminate symbol-function from the language.
> Naturally, a Lisp with no development environment could also have
> symbol-function; the connection is empirical rather than theoretical.
So the env problem is not with symbol-function, but at most only when
symbol-function is combined with something else.
> Common Lisp is not really geared towards minimal application delivery
> because of symbol-function and other similar constructs (and esp. due to the
> lack of any serious standard module/library system), but the problem is, I
> believe, worth considering for future Lisp dialects, as we considered it for
> EuLisp and Ilog Talk, for instance.
I don't think the situation is all that bad. For Franz Lisp, which is
not so very different from Common Lisp, people often treated their
Lisp code pretty much as people treat C code. The main difference
was that Franz had only a file compiler and the compiler was not
part of the normal environment.
And how important is minimal application delivery these days anyway?
Aren't people programming in C++ and Java? The resulting systems tend
to be pretty huge.
If the standard "built in" parts of Common Lisp are in a shared
library, and the cost of one level of indirection when calling
some global functions is not fatal (which it isn't in most cases),
then there doesn't seem to be all that great a problem, even without
magic declarations and the like.
-- jd
Well, to digress, actually I don't mind too much working in Java. It has a
good standard library. The two main things I miss are:
1. Macros.
2. Generic functions.
Muse Prime the company is in stealth mode, so I can't say anything.
> > So you can't
> > easily determine what the delivered application can refer to at runtime,
and
> > therefore minimize the size of the application. Instead, you need to
make
> > the user explicitly state what the runtime components of the app are, or
do
> > some heuristic method like tree-shaking. These methods are unsound
since
> > people can make mistakes and tree-shaking may not cover all necessary
edge
> > cases.
>
> Of course, people can make mistakes; but that's true anyway. If
> the user's code maintains its own mapping from symbols to functions
> (as someone suggests might be done in Dylan), some functions might
> be left out.
Two issues come to mind:
1. The likelihood of people making mistakes, and the pain of maintaining an
external reference list, is quite high in this case compared to, for
instance, simple programming errors.
2. The other big advantage of a completely automated system for managing
dependencies is that it allows the construction of higher-level tools for
managing systems. Forcing humans to intervene at too low a level makes it
much harder to have a good delivery tool.
> Anyway, a Common Lisp implementation could have a way for to declare
> that static analysis limits what what can be called via symbol
> function. (I assume that's not what you meant by "expliticly stating
> what the runtime components are"; and it's static analysis, not a
> heuristic. So it doesn't sound like too bad a solution.)
Jeff, you like to argue about what "could" be the case in implementations,
as if it mattered. I'm not making a theoretical argument. Maybe someone
could do better with Common Lisp, by adding the appropriate pragmas and user
declarations. The fact is, they haven't: there aren't many good delivery
systems in Common Lisp implementations. They all tend to require a lot of
human intervention and maintenance, and are very fragile. One of the cool
things we did with Ilog Talk (IMHO) was to totally automate the process.
You press a button and at the end, voila, a set of files packaged up that
can just be tarred up and shipped. There was essentially no human
declarations other than deciding what goes in which modules, which modules
go in which libraries, and what function is called when an executable is
launched. I believe that the reason we were able to get so far without much
effort (esp. vs the effort expended in other Lisp environments and their,
IMHO again, rather kludgy delivery systems) was because we had a very
pristine model of dependencies that let us generate a dependency graph
automatically.
> And how important is minimal application delivery these days anyway?
> Aren't people programming in C++ and Java? The resulting systems tend
> to be pretty huge.
IDE's are also huge for these languages. If the apps had to ship with them,
they would be that much fatter, as well as including a bunch of crud that
had 0 chance of being executed by the user. (Compared to the various
subfeatures of many consumer apps that have only .5% chance of being
executed by the average user...)
Anyway, as Bill is probably in collusion with hardware manufacturers and so
has strong incentive to continue increasing the size of apps, you might want
to send this idea into Seattle for consideration in future Office releases.
After all, you already get one IDE with Office (VB) - why not two?
-- Harley
> And how important is minimal application delivery these days anyway?
> Aren't people programming in C++ and Java? The resulting systems tend
> to be pretty huge.
RPG said at the recent LUGM that it took some time for him to find
anyone at Sun who could show him a Java application which was less
than 24Mb. Whether that's rutime memory needed or shippable image
size, or something else, I don't know. The recent challenge by Erann
Gat also resulted in lisp memory consumption much less than that for
Java (for a completely non-GUI program).
--tim
Harley,
While you do make a defendable point, I am interested in the following:
how did you patch your applications? What did you do when a standard,
but otherwise not used Lisp function was required in the correction?
Did it automatically become part of the patch?
Robert Monfera
> Jeff, you like to argue about what "could" be the case in implementations,
> as if it mattered. I'm not making a theoretical argument.
I'm talking about what could (theoretically, if you like) be the case,
and that's not ok as a response to a theoetical argument? And this
is (supposedly) about symbol-function, about which you said the
connection with dev envs was "empirical rather than theoretical".
So I will continue to think that the various ways in which
implementations could deal with these problems, some of which are
either already in use or very similar to things used in other Lisps,
are relevant. An interesting question is *why* a greater range of
different CL implementation types do not exist. (I don't know the
answer.) Still, CL does not prevent implementations that care about
creating minimal applications from doing various things about it, and
one of the things they could do is to let the programmer simply say
that symbol-function does not have the "anything might be called"
effect that seemed to be the problem.
Anyway, of the things built into Common Lisp, hardly any of it is
really development. Trace and step come to mind. But assignment to
global variables (which is all setf of symbol-function amounts to)?
I don't think so. Nor is the compiler necessarily development.
*Calling* lots of things in CL development env is a somewhat annoying
rhetorical technique, part of the larger technique of trying to give
the impression that Common Lisp is brain damaged because of some sort
of pernicious mixing of things that any fool knows should be separate:
delivered applications and the dev env.
So there. :-)
(BTW, I agree with your list of Java lacks.)
(That "so there" and smiley were meant to get you to take rather
polemical tone of the above in a spirit of fun rather than as a flame.
I doubted it would suffice; hence this.)
Cheers,
Jeff
All user and system code was stored in shared libraries. You could make
patches by shipping a new shared library, and rerunning the app with a
special flag to redo the dynamic links required for the app. For system
code, we shipped 4 standard shared libraries containing all the system code:
One for the core runtime (essentially the GC), one for the standard
libraries (about 1.5 megs), one for the interpreter, and one for the
compiler and debugging tools. So unless the new required function was in a
shared library that wasn't shipped with the app, there wasn't an issue.
-- Harley
You said it, not me...
> So there. :-)
>
> (BTW, I agree with your list of Java lacks.)
>
> (That "so there" and smiley were meant to get you to take rather
> polemical tone of the above in a spirit of fun rather than as a flame.
> I doubted it would suffice; hence this.)
I got it. How long have we been having this same argument, after all? It
must be 8 years now.
Anyway, in the same vein, I hope nobody took my calling "symbol-function"
"evil" anything other than a rhetorical device to draw out discussion, and
not some actual moral judgment on the designers of Common Lisp...
-- Harley
> Jeff Dalton <je...@todday.aiai.ed.ac.uk> wrote in message
> news:x2zowdh...@todday.aiai.ed.ac.uk...
> > Anyway, of the things built into Common Lisp, hardly any of it is
> > really development. Trace and step come to mind. But assignment to
> > global variables (which is all setf of symbol-function amounts to)?
> > I don't think so. Nor is the compiler necessarily development.
> > *Calling* lots of things in CL development env is a somewhat annoying
> > rhetorical technique, part of the larger technique of trying to give
> > the impression that Common Lisp is brain damaged because of some sort
> > of pernicious mixing of things that any fool knows should be separate:
> > delivered applications and the dev env.
>
> You said it, not me...
Use, mention ... (I didn't say it. I put it in the mouth of this
imaginary rhetorician.)
BTW, I kinda blew it on setf of symbol function. It's the
"redefinition issue" that's straightforwardly just assignment.
> I got it. How long have we been having this same argument, after all? It
> must be 8 years now.
I don't mind the conclusions. Having a built-in table mapping names
to procedures may not be best for many purpoises, and Ilog-Talk-style
implementations are a (but not the only) good thing. But I think it's
essentially a pragmatic issue, and one which different implementations,
and different languages, can reasonably treat in different ways.
Expressing it in terms of dev env contamination of applications, and
making it theoretical, is misleading, indeed tendentious, it seems to
me.
> Anyway, in the same vein, I hope nobody took my calling "symbol-function"
> "evil" anything other than a rhetorical device to draw out discussion, and
> not some actual moral judgment on the designers of Common Lisp...
Just so. But there is a tendency, very noticeable during the
development of Dylan, and also to a significant extent in the
EuLisp world, to describe certain things about Common Lisp, and
sometimes even Lisp in general, including Scheme, as if they
embodied fundamental errors that no one who really knew their
stuff would make.
My view has been that there's more than one good kind of language
and that, usually, things ought to be described with that view in
mind. (Not that I always follow this advice myself, of course.)
-- jeff
> Jeff Dalton <je...@todday.aiai.ed.ac.uk> wrote in message
There are now Linux-libc6 binaries of ILOG Talk (for x86 and sparc platforms)
on ftp://ftp.ilog.fr/pub/Products/Talk/linux/.
New updates will most probably not be made in the future.
Bruno <Hai...@ilog.fr>