> I was thinking about some simple functions for beginners (like myself).
> I want them to have some structure or rules so that for anyone using it
> is simply to predict what its name is going to be, so here are some
> functions for beginners, what do you think of them? Do you think
> anyone would predict the name and use of similar ones? Remember, only
> for beginners :)
I don't really understand what you are trying to do. "Functions for
beginners"? Are these functions to be used by beginners (the concept
does not make much sense, using a function doesn't require a lot of
learning per se), or functions that are designed to teach beginners
Lisp programming and/or good style, or something else?
> (defmacro v.setf (v i val)
> `(setf (aref ,v ,i) ,val))
>
> (defmacro h.setf (h k val)
> `(setf (gethash ,k ,h) ,val))
I don't see the benefit, you introduce obscure notation with no
advantages over the clear & uniform one (setf).
> (defmacro l.new(expr var l &optional i2)
> (if i2 `(loop for ,var from ,l to ,i2 collect ,expr)
> `(loop for ,var in ,l collect ,expr)))
Again, a very obscure dual-purpose macro. If I supply i2, then l is
not a list any more but an index. Not a useful abstraction.
I won't go through the rest, just some general points:
- Common Lispers usually prefer descriptive names, and only write
macros when they are needed. A good style guide is available at
norvig.com/luv-slides.ps
- Don't write macros for other people if you only have a vague idea of
what they should do. Work on a meaningful problem, and write macros
that make _your_ life easier. Some of these may end up being useful
to others if you are lucky, but don't be surprised if that happens
only after the nth redesign.
HTH,
Tamas
> I was thinking about some simple functions for beginners (like
> myself). I want them to have some structure or
> rules so that for anyone using it is simply to predict what its name
> is going to be, so here are some functions
> for beginners, what do you think of them? Do you think anyone would
> predict the name and use of similar ones? Remember, only for
> beginners :)
>
> (defmacro v.setf (v i val)
> (defmacro h.setf (h k val)
> (defmacro l.new(expr var l &optional i2)
> (defun h.new(&optional lst)
> (defmacro v.each (v index &body body)
> (defmacro h.each-key (h k &body body)
> (defmacro h.each-value (h v &body body)
> (defmacro h.each (h k v &body body)
> (defmacro f.each-line(fname line &body body)
Scheme has names like that, vector-set!, list-set!, string-set!, and
even a for-each.
Scheme is designed for beginners...
--
__Pascal Bourguignon__ http://www.informatimago.com/
I'm not a "true lisper". I like lisp environment, but
I believe that lisp syntax is bad. Some time ago I
have learned that sexps were intended to be just
an itermediate syntax and some more human readable
end-user syntax was to be invented. But many time
has gone, no such syntax created and modern
"true lispers" are acquainted with this unncessary
verbosity. So, you'll be unable to make them believe that
(h.setf h k v) is better than
(setf (gethash h k) v)
despite the evident fact that first variant is
less verbose.
(h.setf k v) would be even better,
and
h[k]=v; would be even more better.
But no one true lisper would agree that.
What can I say? setf syntax do have
some advantages as it can accept several argument
and you can define setf expanders.
Also, gethash has an advantage of static typing.
When you write gethash, you "declare" that first
argument will be a hash table. If you have
just [] operator in a language and
apply it to a hash table, you either have
to declare explicitly that h is a hash table
(static typing) or find a [] method at runtime,
which would make things slower. But you
like CL as it is fast and maybe you
are not agree to pay that high price for
syntax "sweetness".
So, if you want convinience of Ruby syntax,
you might want to develop entirely new
syntax for lisp platform. There is a plenty
of languages for Java Platform, one might
develop new language for Common Lisp platform
too. Common Lisp is a rather good platform,
IMO it has a better architecture than Java.
I dislike JIT. Good Common Lisp
implementation have native code compilers
which work when you call them and not when
engine decides your code is called
sufficiently many times.
So, take Common Lisp as a platform and
intermediate language. You might succeed,
but this would be a large work. There
already is (somewhat unfinished)
"PythonLisp".
Yes, this would be hard to do
and maybe that "Ruby in Lisp" would be
essentially slower than Lisp itself.
If you do not want to do such work, you'd better
comply to lisp's style and don't complain. This
is just a price for benefits of CL. If you
want use your macros, use them for yourself
and be sure your code would be criticised
by "true lispers".
> budden ha escrito:
>> Hi Eduitnoa, list!
>>
>> [...]
>
> Hello budden, thanks a lot for your comments, I agree with you 99.9 \
> %, is great to find a person who thinks
> like you/me.
>
> Observe that h.sef is designed for speed. The idea of using the
> prefix h. for hashes is a middle one:
> you obtain a little bit of good syntax and the macro get expanded into
> lisp code, so no problem with speed.
>
> Glad to hear from you.
>
> I think it should be possible to follow this path, but as you say it
> would be a lot of work to translate from ruby
> to obtain macros in Lisp.
Have a look at:
http://www.informatimago.com/develop/lisp/small-cl-pgms/m-expression/
It is rather trivial to put a syntax over s-exps.
What occured between S-exps and M-exps, is that somebody invented
macros in between. And writing macros for M-exps or anything else
than S-exps is less convenient, much less inconvenient than the
advantages gained from macros. So lispers choosed to keep macros and
forgot about concrete syntaxes, for themselves. Of course, we keep
writing concrete syntaxes for less advanced users.
For example, Guy L. Steele, a very advanced lisper, wrote the
specifications of Java, for less advanced programmers (there's no
macro in Java).
Yukihiro Matsumoto, a well versed lisp programmer, wrote Ruby for
less advanced programmers (there's no macro in Ruby).
Peter Norvig, a very good lisper, now teaches Python to his less
advanced programmer students (there's no macro in Python).
You could go on an on...
Now, to make writing macros in any programming language easy and safe,
you only need to have a flexible data structure to represent the code
(strings are not a flexible data structure for that purpose), and to
have homoiconicity to avoid impedence mismatch between code and data
(this makes it harder to understand the working of macros). The
details of the syntax or the data structure are not important. I hear
XML and XSLT does something like that. It just occurs that lists are
more flexible than trees or arrays, and that writing just the elements
of the lists in parentheses is the simpliest concrete syntax you can
imagine. Therefore S-exps are the simpliest and probably the most
effective way to have a homoiconic and flexible encoding system to
write macros easily and safely. It's not a dogma, it's a discovery.
You could find some easier system, but people have been searching one
for 50 years now without finding any.
> Thanks to Pascal B, he always give good advice and it seems he knows
> Lisp very well. I was surprised that
> he criticized Gavino IQ, Pascal B. is always (with some exceptions) a
> nice guy.
Either that says something about gavino, or about me! :-)
> Happy new year to everyone.
Happy 2010!
I've tried to approach it here:
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/b69c6e5e7b675d16#
This can't be done for hash tables, but this can
be done with symbols and defstructs.
E.g.,
(with-typed-object (x my-struct-type (make-my-struct-type))
(setf x.field1 x.field2))
or, say,
(with-typed-object (var symbol)
(print var.name))
would expand to:
(let ()
(declare (symbol var)
(print (symbol-name var))
)
This is done just by creating symbols with
prefixed names. If gethash was called
hash-get, then this would work for hashes
like this:
(with-typed-object (var hash (make-hash-table))
(var.get key default))
But gethash is called gethash, so this is not the case.
And, it is easily seen that first line is rather verbose too.
Anyway, if you try to generalize your approach, you
likely would come to a conclusion you'd better
developed a completely new language on top of Common Lisp.
E.g.,you'd prefer your macroexpanded code would be printed
in a terser form, not in verbose macroexpanded form.
> What occured between S-exps and M-exps, is that
> somebody invented macros in between. And writing macros
> for M-exps or anything else than S-exps is less convenient,
> much less inconvenient than the advantages gained from
> macros. So lispers choosed to keep macros and
> forgot about concrete syntaxes, for themselves.
> Of course, we keep writing concrete syntaxes for
> less advanced users.
I don't think lispers are stupid. I don't know what to think.
Maybe this is a religious abberation of mind, or this is
some conspiracy. Maybe lisp was to powerful and Big Brother
decided to introduce some mess...
In fact, macros can be done easily with M-expressions too.
Look at M4 to get the idea. C is rather eager language which
uses almost every ASCII character. Anyway, M4 took just
one character "`" and built its macro-system around it
with a great success. I see no reason why this can't
be done with M-expressions or any other reasonable syntax.
Instead of that, what we have now? We have unreasonable
s-expression syntax. Many people (not only beginners)
are getting annoyed of it. And they reinvent a wheel again
and again. All these aifs, with-struct*, defclazz, etc.
Macros are too easy. In fact, macros hold about 5-10% of
all definitions. If they were bit more difficult to write,
this would not be a great disadvantage of a language, if
we could get sane base syntax instead.
E.g. you might take a look at some other languages,
e.g. there is Boo - python-like, statically typed,
dynamically implemented language with macros for #net.
All this almost have inspired me to make such a
language built on top of Lisp by myself. Things
I've done before (efforts to fix package system,
symbol-readmacros, proga macro) was the preliminary
steps to do. Now I see I can't make lisp more terse
and more convinient without essential changes to
lisp itself. I'm in process of migrating all my code
to CCL. If I succeed, this is likely that I'll start
to create the language.
Unfortunately it looks like it is hard to make a
new language in a portable CL, as CL does not
expose its internals. I mean, I have no
sufficient access to compiler/reader/printer
internals in portable CL. It was rather hard to
make a reader work correctly when I have added
symbol-readmacros.
Printing can't be changed either: e.g. I can't,
generally speaking, define print-object on symbol
- many implementations just ignore it. If I could,
I could fix annoying "feature" of symbol name
upcasing.
So my plan is to fork CCL to have more freedom.
Unfortunately writing such a language is rather
hard work anyway and it looks like I'm too lazy to
complete such a work. I'm unsure if I have enough
persistency to finish it by myself, so if someone
is interested in collaborating/funding, feel free
to contact me.
> (strings are not a flexible data structure
> for that purpose),
My practice shows that m4 is rather powerful
and it allows to bypass some of C++ limitations, despite
the fact that m4 is mostly string-based and simple
while C++ templates are much more complex.
> You could find some easier system, but people have
> been searching one for 50 years now without
> finding any.
Nope. m4 is a counter-example. You could find m4 is
used extremely widely in UNIX world. If something
exist and people can't see that, I think it is a
dogma.
Another, yet more popular counter-example is a... bash!
Its recursive substitution looks very similar to
macroexpansion. I don't mean to say bash is simple
and convinient as a macroexpander though.
Hey, budden,
I programmed a couple of years ago an m4 preprocessor for a
makefile. I must say that the resulting code looked a lot like lisp,
with the difference that functions are written f(args), instead of (f
args). The recommended way of iteration is even tail recursion.
Regards,
Jurgen
> and we would like that for example python.
>
> [i^2 for i in range(20)] can be used as ( l.new( (* i i) i 0 19)
(mapcar 'square (range 20))
> [i^2 for i in list] can be used as (l.new ( (* i i) i list)
(mapcar 'square list)
Sorry, the advantage of your notation is not clear to me.
Nicolas
P.S.: If you should not have the SQUARE function write it, or use
something like
;; using currying:
(mapcar (rcurry 'expt 2) list)
;; using the Infix library and a lambda abbreviation:
(mapcar (_ #I"_^^2") list)
...
er> (defmacro h.setf (h k val)
er> `(setf (gethash ,k ,h) ,val))
This makes no sense. If somebody wants to use array, he needs to know about
aref (or elt) function.
Then using (setf (aref ...) ...) is trivial.
Same way, if somebody wants to use hash-tables, he needs to know about
gethash.
If you will also make v.get (for example) function, that will be another
story, but I don't think that finding v.get is easier than finding aref.
I do not think it is that hard do find aref -- open hyperspec, there is
Arrays chapter, and there is dictionary there.
er> (defmacro l.new(expr var l &optional i2)
er> (if i2 `(loop for ,var from ,l to ,i2 collect ,expr)
er> `(loop for ,var in ,l collect ,expr)))
LOOP notation is already pretty intuitive -- you can read it and write it
like plain English.
Unlike your l.new macro.
er> (defun h.new(&optional lst)
er> (let ((h1 (make-hash-table :test #'equal)))
er> (when lst
er> (loop for (k v) in lst do
er> (h.setf h1 k v)))
er> h1))
As utility function it is useful, but it essentially does list->hast-table
conversion, it is not hash-table constructor.
er> (defmacro v.each (v index &body body)
er> `(dotimes (,index (length ,v))
er> (progn ,@body)))
I do not think it does what it is supposed to do.
er> (defmacro h.each (h k v &body body)
er> `(loop for ,k being each hash-key of ,h
er> using (hash-value ,v) do (progn ,@body)))
maphash
>> > Observe that h.sef is designed for speed.
>> > The idea of using the
>> > prefix h. for hashes is a middle one: you obtain a little bit of good
>> > syntax and the macro get expanded into
>> > lisp code, so no problem with speed.
> In fact, static typing would be the best approach to combine both speed
> and terseness of code. E.g. (declare (hash-table var))
> (var.setf k v))
I don't see why you need static typing, and why it would be the best
approach, given the related disadvantages (which have been discussed a
zillion times on c.l.l). Accessors as generic functions could also
work if you want "terse" code, you can do that as a thin layer on
current CL. Declaring the type, your compiler can optimize, there is
no need for static typing.
> easily seen that first line is rather verbose too. Anyway, if you try to
> generalize your approach, you likely would come to a conclusion you'd
> better developed a completely new language on top of Common Lisp.
> E.g.,you'd prefer your macroexpanded code would be printed in a terser
> form, not in verbose macroexpanded form.
New Lisp-like languages have been developed, eg Qi and Qi II. They
have some nice features, and it is claimed that they lead to very
terse & fast code (http://www.lambdassociates.org/faq1.htm).
> Macros are too easy. In fact, macros hold about 5-10% of all
> definitions. If they were bit more difficult to write, this would not be
> a great disadvantage of a language, if we could get sane base syntax
> instead.
CL has benefited a lot from the accessibility of macros. Some
constructs developed in CL's predecessors ended up in the CL standard,
and some more recent macros are now a de facto standard (eg bind,
iterate). I don't see how making macros more difficult would lead to
"sane base syntax", rather the opposite. Languages without macros
don't magically end up with "better" syntax in general. Usually, the
best that happens is that some languages end up with domain-specific
syntax that works well in some cases, but fails to be convenient
outside the prescribed domain. This is realized later in the life
cycle of the language when people try to write more complicated code.
Alas, clever syntax for one-liners means very little.
> All this almost have inspired me to make such a language built on top of
> Lisp by myself. Things I've done before (efforts to fix package system,
My perception is that very few people would consider your changes to
the package system a "fix". It ain't broken. (Yes, I know, Lispers
are stupid, blinded by bigotry, etc).
> Unfortunately it looks like it is hard to make a new language in a
> portable CL, as CL does not expose its internals. I mean, I have no
You can just write a compiler in CL -- again, look at Qi.
> Printing can't be changed either: e.g. I can't, generally speaking,
> define print-object on symbol - many implementations just ignore it. If
> I could, I could fix annoying "feature" of symbol name upcasing.
I think you are getting bogged down by irrelevant details.
>> You could find some easier system, but people have
>> been searching one for 50 years now without
>> finding any.
> Nope. m4 is a counter-example. You could find m4 is used extremely
> widely in UNIX world. If something exist and people can't see that, I
> think it is a dogma.
The fact that m4 is used widely does not mean that it is as powerful
as CL macros. For example, the number of people who are able to
perform arithmetic with small integers is significantly higher than
mathematicians trained in abstract algebra, but that does not mean
that the former is more powerful than the latter. Please provide
arguments based on technical merit, not popularity.
Best,
Tamas
> I was thinking about some simple functions for beginners (like
> myself). I want them to have some structure or
> rules so that for anyone using it is simply to predict what its name
> is going to be, so here are some functions
> for beginners, what do you think of them? Do you think anyone would
> predict the name and use of similar ones? Remember, only for
> beginners :)
>
> (defmacro v.setf (v i val)
> `(setf (aref ,v ,i) ,val))
>
> (defmacro h.setf (h k val)
> `(setf (gethash ,k ,h) ,val))
Awkward. Now beginners are expected to learn both aref and v.setf to
work with arrays, rather than just using aref with setf?
> (defmacro l.new(expr var l &optional i2)
> (if i2 `(loop for ,var from ,l to ,i2 collect ,expr)
> `(loop for ,var in ,l collect ,expr)))
This is a weird set of parameters. Instead of having expr up front, put
a body parameter at the end like every other body-taking macro does, and
make it an implicit progn. I suppose maybe you did not do this because
you couldn't make it work with the optional parameter? Here's how:
(defmacro l.new ((var l &optional i2) &body body)
(if i2
`(loop for ,var from ,l to ,i2 collect (progn ,@body))
`(loop for ,var in ,l collect (progn ,@body))))
(l.new (x 3 5)
(print x)
(+ x 1))
It still behaves completely differently when i2 is supplied, and even
requires a different type for one parameter. Confusing. Better to make
two macros (or functions) if you have two different things to
do. Especially when one is basically mapcar and the other could
sometimes be mapcar with iota.
(defun iota (end &optional (start 0))
(loop for i from start to end collect i))
> (defun h.new(&optional lst)
> (let ((h1 (make-hash-table :test #'equal)))
> (when lst
> (loop for (k v) in lst do
> (h.setf h1 k v)))
> h1))
Why does this do something completely different from l.new? It doesn't
even take an expression. At least one of the two should probably have a
different name.
> (defmacro v.each (v index &body body)
> `(dotimes (,index (length ,v))
> (progn ,@body)))
>
> (defmacro h.each-key (h k &body body)
> `(loop for ,k being each hash-key of ,h do (progn ,@body)))
>
> (defmacro h.each-value (h v &body body)
> `(loop for ,v being each hash-value of ,h do (progn ,@body)))
>
> (defmacro h.each (h k v &body body)
> `(loop for ,k being each hash-key of ,h
> using (hash-value ,v) do (progn ,@body)))
>
>
> (defmacro f.each-line(fname line &body body)
> `(with-open-file (f ,fname)
> (loop for ,line = (read-line f nil 'eof)
> until (eq ,line 'eof) do (progn ,@body))))
How often do you do any of this? Is it going to be faster and easier to
remember one of these obscure functions and read it to find out what its
parameters mean than to write it when you need it? And wouldn't
beginners who can't write these do better to learn how?
The faux-OO names are a strange choice, especially since these are
designed to ignore all of CL's polymorphic capabilites. Why not use setf
and CLOS and get the real thing
Don't assume that 'terseness' is a quality in a programming language.
Being able to read and understand your and other people's code tomorrow
is much more important than saving a few keystrokes today.
> (declare (hash-table var))
> (var.setf k v))
>
> I've tried to approach it here:
> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/b69c6e5e7b675d16#
>
> This can't be done for hash tables, but this can
> be done with symbols and defstructs.
> E.g.,
> (with-typed-object (x my-struct-type (make-my-struct-type))
> (setf x.field1 x.field2))
>
> or, say,
> (with-typed-object (var symbol)
> (print var.name))
>
> would expand to:
> (let ()
> (declare (symbol var)
> (print (symbol-name var))
> )
>
> This is done just by creating symbols with
> prefixed names. If gethash was called
> hash-get, then this would work for hashes
> like this:
>
> (with-typed-object (var hash (make-hash-table))
> (var.get key default))
>
> But gethash is called gethash, so this is not the case.
Well, it wouldn't be too hard to take care of this special case in the
WITH-TYPED-OBJECT macro, if you really wanted to...
> And, it is easily seen that first line is rather verbose too.
> Anyway, if you try to generalize your approach, you
> likely would come to a conclusion you'd better
> developed a completely new language on top of Common Lisp.
> E.g.,you'd prefer your macroexpanded code would be printed
> in a terser form, not in verbose macroexpanded form.
Why should you care about the verbosity of a macroexpansion? That's only
for the compiler to see.
> [...]
> Macros are too easy. In fact, macros hold about 5-10% of
> all definitions. If they were bit more difficult to write,
> this would not be a great disadvantage of a language, if
> we could get sane base syntax instead.
I'm pretty sure this is the first time I hear someone advocating for
making a programming language *more* difficult to use (except for the
INTERCAL designers, of course... :)
> E.g. you might take a look at some other languages,
> e.g. there is Boo - python-like, statically typed,
> dynamically implemented language with macros for #net.
>
> All this almost have inspired me to make such a
> language built on top of Lisp by myself. Things
> I've done before (efforts to fix package system,
> symbol-readmacros, proga macro) was the preliminary
> steps to do. Now I see I can't make lisp more terse
> and more convinient without essential changes to
> lisp itself. I'm in process of migrating all my code
> to CCL. If I succeed, this is likely that I'll start
> to create the language.
>
> Unfortunately it looks like it is hard to make a
> new language in a portable CL, as CL does not
> expose its internals. I mean, I have no
> sufficient access to compiler/reader/printer
> internals in portable CL. It was rather hard to
> make a reader work correctly when I have added
> symbol-readmacros.
Are you sure it was CL's fault? :)
> Printing can't be changed either: e.g. I can't,
> generally speaking, define print-object on symbol
> - many implementations just ignore it. If I could,
> I could fix annoying "feature" of symbol name
> upcasing.
Symbol name upcasing has nothing to do with printing.
Alberto
> Paul Donnelly ha escrito:
>> eduitnoa rubicubez <ruli...@gmail.com> writes:
>>
>> > (defmacro f.each-line(fname line &body body)
>> > `(with-open-file (f ,fname)
>> > (loop for ,line = (read-line f nil 'eof)
>> > until (eq ,line 'eof) do (progn ,@body))))
>>
>> How often do you do any of this? Is it going to be faster and easier to
>> remember one of these obscure functions and read it to find out what its
>> parameters mean than to write it when you need it? And wouldn't
>> beginners who can't write these do better to learn how?
>>
>> The faux-OO names are a strange choice, especially since these are
>> designed to ignore all of CL's polymorphic capabilites. Why not use setf
>> and CLOS and get the real thing
>
>
> I think this functions are for beginners in Lisp that can program in
> Python and Ruby. l.new and h.new
> are unexpected I agree.
The important keyword was CLOS. Learn more about Common Lisp (or
Scheme if you've got a specific interest into beginners), before
trying to invent new stuff.
> I think this functions are for beginners in Lisp that can program in
> Python and Ruby. l.new and h.new are unexpected I agree.
Your suggested syntax layer is not an improvement over current CL,
rather the opposite. Even if it was equally good, changing it to look
like Ruby doesn't help beginners at all. CL has developed very nice
ways to organize accessors, mappings, and iteration, and beginners
usually pick up these concepts in no time: these are _not_ the hard
parts of CL.
Newbies often need help with the package system, more obscure parts of
CLOS (and the MOP), macros, and learning good Lisp style in general.
Efforts to help them are laudable, but please learn CL first before
you try to help others.
> but I think that for example h.length is more expected than hash-table-
> count.
Not in Common Lisp.
> I should say that using h.setf v.setf and a.setf is a more uniform way
> of expression setf.
It is not. (setf accessor) is the general pattern: I only need to
remember the name of the accessor. You are confused because you come
from a language without macros where things like setf would be
impossible.
> remember the problem with the order of the arguments in aref and gethash
There is no problem. If you can't remember it, just use a reasonably
good IDE and it will remind you (eg SLIME).
> Thanks for sharing you impressions. I don't want to sell anything. I
> am just learning Lisp and thinking about what I learn.
Learning a language is a good thing, but don't make the mistake of
trying to bend it to look like another language you already know,
because then you are not learning anything. Lisp is different for a
reason.
HTH,
Tamas
> Paul Donnelly :
>> (defun h.new(&optional lst)
>> (let ((h1 (make-hash-table :test #'equal)))
>> (when lst
>> (loop for (k v) in lst do
>> (h.setf h1 k v)))
>> h1))
>>
>> Why does this do something completely different from l.new? It
>> doesn't even take an expression. At least one of the two should
>> probably have a different name.
>
> I agree that this is different from l.new, but you can just apply
> h.new to l.new to get the function you want, also h.new is really a
> list to hash-table transformer. So perhaps this is not so bad.
The question is why "new" means something completely different for hash
tables than for lists. I see that h.new is really a list to hash table
transformer. But why is it given something else's name instead?
> Paul Donnelly ha escrito:
>> eduitnoa rubicubez <ruli...@gmail.com> writes:
>
> I think this functions are for beginners in Lisp that can program in
> Python and Ruby. l.new and h.new are unexpected I agree.
>
> but I think that for example h.length is more expected than hash-table-
> count.
I don't know, I never though of hash tables as having a length, although
I suppose Python or Ruby programmers might. But I think putting dots in
to make it look more like Ruby code would be more likely to confuse
them--they'll say, "How come methods in Lisp belong to types and I have
to put the object later?" Hopefully it doesn't take too long before
someone tells them that these are just function names and OO in Lisp
looks completely different.
> I should say that using h.setf v.setf and a.setf is a more uniform way
> of expression setf.
>
> remember the problem with the order of the arguments in aref and
> gethash
These could be more uniform.
> also why gethash and not hashget,
Because it was named by an English speaker. ;)
> and there is aref ...
Names could be more uniform too, yes. If you desire a more uniform set
of names and arguments, why not write a uniform set of wrappers for
gethash and so on that will work with setf, and see how you like that?
You might also try writing your .new macros and others as methods.
What goes to static typing, boundary between static and dynamic
typing gets somewhat blurred when we have RTTI and variant types
in a statically typed language. In Object Pascal (Delphi) there
is a common predecessor of most classes: TObject, where we
get class-name and class-of. Also there are "is" (typep) and
"as" (something like check-type). After some training
I found that I can code in Delphi almost as polymophically as
I can do with Lisp, despite the fact Delphi is statically
typed. But there are class.method and class.field notations,
implicit "self" field, with ... do ... constructs in Object
Pascal. These can discriminate method bodies at
compile time as language is statically typed. In CL, when
I just declare variable to have some type, I still can't get
shorter name for its fields (when we talk about structures).
So, static typing serves for expressiveness. It could do so
in Lisp too, but it does not due to design of CL.
Proposed with-typed-object macro helps this a bit, but this
is not a complete and perfect solution.
> I don't see how making macros more difficult would lead to
"sane base syntax", rather the opposite.
This can't occur automagically. But if macros are hard, language
designer would need to work out base syntax more carefully.
> You can just write a compiler in CL -- again, look at Qi.
Thanks, I'll take a look at it again, I'm not a fan of OCaml
though. I just mean that making lisp compiler to compile some
other language would be not that easy. E.g. we have no
full access to macroexpansion environments.
> My perception is that very few people would consider your changes to
the package system a "fix".
In fact, I gave up most of them as they hard to implement
portably. All I left in use now is "auto-import" which suggests
a simple policy to combine clashing packages without a headache
and "forbidden-symbol-names" which help diagnose trash symbols.
Couple other utilities would make me reconcile oneself with
package system.
> The fact that m4 is used widely does not mean that it is as powerful
> as CL macros.
Where did I say this? I state only that m4 is as easy as CL's
macros and it is string-based, not sexp-based. I never said it
is as powerful as CL's macros as this is just not true.
> So lispers choosed to keep macros and
> forgot about concrete syntaxes, for themselves.
It looks like lispers aren't any good at syntax.
> Of course, we keep
> writing concrete syntaxes for less advanced users.
The frightened man whistles gaily as he passes the graveyard.
--
I do not know Ruby, but I'm pretty sure there are some design
differences, so this would be not that easy to implement. Maybe you
(we?) could make a Ruby-like syntax for lisp. But I prefer Pascal, as
static typing allows it to be more expressive in most times. Just
adding CL's T type to Pascal helps to avoid all static typing
limitations.
Some time ago I have issued my budden-tools library. Now I'm in
process
of preparing its second edition. One of its features is "custom token
parser".
With my library, one can intercept call from reader to INTERN and
treat
symbol name as something arbitrary, depending on *package* or package
qualifier.
E.g. I have arranged things so that date:2010-01-05 would read as
local-time:timestamp value by CL. This is convinient and I use this
every day. It is also possible with my library to read any-package:a.b
as
(any-package::dots a b). This could be a base entry point into a new
syntax.
Make dots a macro and then you can use a.b syntax as freely as you
do in Ruby. If you're interested you could wait for a release of
my library, this would take about couple of months. Meanwhile you
could deepen your CL knowledge.
> differences, so this would be not that easy to implement. Maybe you
> (we?) could make a Ruby-like syntax for lisp. But I prefer Pascal, as
> static typing allows it to be more expressive in most times. Just adding
Nay, Wirth's Pascal is still too nice. Typically, it takes about 1-2
hours of programming in Pascal to make the average person loathe
programming forever. I think that Fortran IV would be a better
choice, with smartass features like logical IF statements disabled.
> CL's T type to Pascal helps to avoid all static typing limitations.
Sure. And adding parentheses to Pascal would make it Lisp. Wait, it
already has ()'s. Now I am confused.
> Some time ago I have issued my budden-tools library. Now I'm in process
> of preparing its second edition. One of its features is "custom token
> parser".
> With my library, one can intercept call from reader to INTERN and treat
> symbol name as something arbitrary, depending on *package* or package
> qualifier.
Why would I need that? Especially now that I have Budden's Extended
Pascal, with static typing, which is "more expressive in most times".
And it even has the type T. And parentheses! The very idea makes me
overexcited. I have to go and take a cold shower now.
Best,
Tamas
> Why would I need that?
You really don't need any of my code, you're
true lisper.
>> Nay, Wirth's Pascal is still too nice.
> I mean Object Pascal. It differs very significantly from original
> Pascal. It has classes, interfaces, polymorphic arrays, e.g. you can
> write foo([1,'abc',TObject.Create,valueOfOtherType]); What it misses
> compared to CL are macros, dynamic recompilation, GC.
Wow. Checking the Wikipedia page shows that it has 5+ minor variants.
That is the sign of a Truly Great Programming Language: if you can't get
it right, try banging your head against the same wall, but wearing a
different colored hat each time (whereas sissies like lispers would just
make their language extensible). Thanks for reminding me that there
are languages that are f*d up even beyond C++, which itself is quite
an achievement. Programming Lisp, I tend to forget about the horrors
that are out there. Delphi is a gem.
And given the fact that you are a fan of static typing, I am glad that
you aimed for Pascal instead of ML-like languages. It is good to see
that the true spirit of bondage & discipline programming lives on.
Real Men don't trust the compiler to infer their types; also, if you are
paid by the line, languages like Pascal come in handy.
>> Why would I need that?
> You really don't need any of my code, you're true lisper.
Thanks for the compliment, it is something I am working towards.
Maybe in a few years I will deserve it.
Best,
Tamas
>Real Men don't trust the compiler to infer their types;
Sometimes I find it stupid not to infer types. E.g. char c='a';
But this won't work in all cases. Is it int i=1 or unsigned int i=1?
>And given the fact that you are a fan of static typing, I am glad that
>you aimed for Pascal instead of ML-like languages. It is good to see
>that the true spirit of bondage & discipline programming lives on.
You might want to take a look at Pascal vs Ocaml.
http://shootout.alioth.debian.org/u64/benchmark.php?test=all&lang=fpascal&lang2=ocaml
You see, Ocaml is neither terser nor faster than Pascal and it uses
much
more memory on the examples considered. I have a friend who have
learned
Ocaml, tried it for some projects and finally he disappointed. It has
some
serious design flaws. I'm still not as disappointed in CL as he is
disappointed in Ocaml.
Well, I think this discussion is not very productive )
|> You really don't need any of my code, you're true lisper.
|
| Thanks for the compliment, it is something I am working towards.
| Maybe in a few years I will deserve it.
Personally I think it may be better if you stuck to statistics. It
would be better than `usenet flaming' which appears to be your real core
competency.
--
Madhu
> Pascal J. Bourguignon wrote:
>
>> So lispers choosed to keep macros and
>> forgot about concrete syntaxes, for themselves.
>
> It looks like lispers aren't any good at syntax.
It's a deliberate choice.
Most other programming languages differ only by the syntax. Instead
of losing time in searching a perfect syntax, lispers prefer to spend
time on harder problems, such as AI.
Mr. James is especially bad at syntax, worse than any Lisper:
-----
William James, 18 Dez. 2009, 19:55
Yukihiro Matsumoto wrote:
> Hi,
> In message "Re: Math errors"
> on Fri, 18 Dec 2009 17:30:15 +0900, "W. James"
> <w_a_x_...@yahoo.com> writes:
> |irb(main):007:0> -27 ** (1/3.0)
> |=> -3.0
> It's -(27 ** (1/3.0)).
> matz.
Thanks for the explanation.
-----
-27 ** (1/3.0) is the same as -(27 ** (1/3.0)) ... in Ruby.
Let's see what the new large scheme will turn out. R6RS seems like an
abandoned child.
Slobodan
Slobodan