Hi,
Maybe it's a stupid newbie question but how to return exactly the same
symbol from the list as initially defined?
Let's say I have a code:
(setq *assoc-func* (list (list (list 'G 1) 'GetInput)
(list (list 'S 1) 'SetInput)))
(defun DefAlienFunc (assoclist)
(if (not (null assoclist))
(let ((sDefAlienFunc (format nil "~aC" (cadar assoclist))))
(def-alien-routine sDefAlienFunc void (fd integer) (param (* t)))
(DefAlienFunc (cdr assoclist)))))
(DefAlienFunc *assoc-func*)
All I want here is to define alien routines with "C" suffix like
"GetInputC", "SetInputC" etc. All I get is "GETINPUTC" and "SETINPUTC"
function defined.
Is there any way to prevent c[ad]r functions from returning
captitalized symbols?
If I do it this way:
(setq *assoc-func* (list (list (list 'G 1) "GetInput")
(list (list 'S 1) "SetInput")))
then I have a problem calling a lisp function (defun GetInput ....)
because I return the function name from the *assoc-func* list and it's
string instead of a symbol:
(funcall (GetAssocFunc *assoc-func* *param-list*) fd)
If I try:
(funcall (coerce (GetAssocFunc *assoc-func* *param-list*) 'function)
fd)
The debugger complains that it cannot find source for the function.
Hope my question is not too messy :)
Thanks is advance,
Andrew
Andrei wrote:
> Hi,
> Maybe it's a stupid newbie question but how to return exactly the same
> symbol from the list as initially defined?
One way is to use bars when coding the symbol:
Without:
CLO(2): 'cello
CELLO
CLO(3): (symbol-name *)
"CELLO"
With:
CLO(4): '|Cello|
|Cello|
CLO(5): (symbol-name *)
"Cello"
There is some "modern mode" or something in which I /think/ a Lisp will
honor the coded case, but I am not sure.
>
> Let's say I have a code:
>
> (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> (list (list 'S 1) 'SetInput)))
> (defun DefAlienFunc (assoclist)
> (if (not (null assoclist))
> (let ((sDefAlienFunc (format nil "~aC" (cadar assoclist))))
> (def-alien-routine sDefAlienFunc void (fd integer) (param (* t)))
> (DefAlienFunc (cdr assoclist)))))
>
> (DefAlienFunc *assoc-func*)
>
> All I want here is to define alien routines with "C" suffix like
> "GetInputC", "SetInputC" etc. All I get is "GETINPUTC" and "SETINPUTC"
> function defined.
What I did was hack up a little translation function which took a name
such as GetInputC and converted it to get-input-c. If you use bars when
coding the symbol then you have to also call it via (|GetInputC|...). By
hypenating the original camelCase you avoid that and get brownie points
from the Lisp Purity Squad for not using camelCase.
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Andrei Stebakov wrote:
> Maybe it's a stupid newbie question but how to return exactly the same
> symbol from the list as initially defined?
(You've already had a practically-focused reply from
Kenny Tilton. This is a more theoretical one, which
won't answer the question you actually asked but might
help you to understand that there was something wrong
with it.)
Whoa, stop right there. You have a misunderstanding
that needs to be cleared up ...
When you say something like
(setq foo (list 'GetInput))
it's not LIST or SETQ that's responsible for the upper-casing
of the symbol name, still less is it CAR when you retrieve
the symbol from the list later.
The upcasing happens at *read* time, before anything gets
compiled or evaluated. As soon as any bit of your Lisp
system other than the very front end sees the symbol
that you've written as "GetInput", what it sees is a
symbol whose name is actually "GETINPUT". THe upcasing
is done by the "reader", which is the part of your Lisp
system that converts characters into Lisp objects before
they are processed further.
If you type
'GetInput
into your Lisp system, what it displays back at you
will probably be
GETINPUT
(though it might conceivably be all lower-case instead,
for reasons I won't go into right now).
Here's what happens when you type
(setq foo 'GetInput)
into your Lisp system.
1. The reader reads the characters and spits out a
Lisp object. The object in question is a list with
the following structure. (If you aren't reading
this in a monospaced font, prepare to be very
confused.)
+----+--+ +---+--+ +---+---+
|SETQ| -+-->|FOO| -+-->| . |nil|
+----+--+ +---+--+ +-+-+---+
|
V
+-----+--+ +--------+---+
|QUOTE| -+-->|GETINPUT|nil|
+-----+--+ +--------+---+
In other words, this is a complicated structure made
out of five "cons cells", four symbols and two instances
of the thing I've denoted "nil" (which is in fact a
symbol called "NIL" but is unusual in enough ways that
I wanted to represent it differently), with pointers
between the cells. Symbols are themselves quite
complicated things, in fact, and really each of
those symbols would be better represented as a
pointer to an object containing the details of the
symbol.
At this point, the original characters you typed
are *gone*. Nothing other than the reader ever cares
about them. Everything else is defined in terms of
the structure.
Note that the symbol is already all-uppercase. That's
a defined part of the reader's behaviour.
2. This structure is passed to whatever bit(s) of the
system are concerned with evaluating expressions.
That might be an interpreter that walks over the
structure doing stuff with it. It might be a byte-code
compiler that generates bytecode and feeds it to a
virtual machine. Or it might be a native-code compiler
that generates machine code and jumps straight to it.
Let's suppose it's the last of these, as it is in
some popular Lisp systems. Then, typically ...
3. The next thing that happens is a process called
"macroexpansion". In this particular case, it does
nothing.
4. Then the structure is handed over to the compiler.
It does whatever complicated thing compilers do,
and it produces some machine code that does what
you've told it to do. Here's roughly what it might
look like (imaginary code for an imaginary processor
running an imaginary Lisp system):
mov a1, immediate 0x00783078 ; GETINPUT
mov a2, immediate 0x00789A00 ; FOO
str a1, a2 + 24 ; store GETINPUT in FOO's value slot
ret ; done! (Result is still in register a1.)
The compiler knows that the GETINPUT symbol object
has address 0x00783078 and that the FOO symbol object
has address 0x00789A00. (They might move when garbage
collection happens. If so, the garbage collector will
patch up the addresses. Most Lisp systems actually
have another layer of indirection so that the GC doesn't
need to change actual code, for several reasons. If
you don't understand this parenthesis, ignore it.)
5. The code gets called.
6. The result of executing it is passed to another
bit of your Lisp system, called the "printer".
Its job is to convert Lisp objects to characters;
it's the inverse of the reader. It is handed a
particularly simple Lisp object, namely the symbol
GETINPUT. (What this means in practice is typically
that it's passed a pointer to the symbol object.)
7. The printer looks up the name of the symbol. It's
"GETINPUT". So it writes that name to the output
stream. We're done.
This is all under the control of a little bit of code
called the "read-eval-print loop", or REPL for short.
An oversimplified version of it would look something
like this:
(loop (print (eval (read))))
The call to READ is step 1. The fact that EVAL gets
the result of calling READ is step 2. What EVAL might
do is described in steps 3,4,5. The fact that PRINT
is passed the result of calling EVAL is step 6. What
PRINT does is step 7. And because the whole thing is
in a loop, after doing step 7 we go back to step 1
again: read another form, evaluate it, print the
result, and so on until you quit.
This differs from what happens in most other languages.
- Some languages don't have an interactive mode
at all. For instance, if you're writing a program
in FORTRAN or C++, you feed the source code to
a separate program, which generates an object
file, and then you run the object file.
What Lisp does is better than that, because it
lets you interact with the system as it runs.
You can change your code, look at values of
variables, try out experiments, and so on.
(A good debugger for a conventional language
lets you do some of these things.)
- Even in languages that do have an interactive mode,
the reader is often not separated from the compiler
or interpreter. Instead, the compiler or interpreter
gets fed a string of characters and it works with
those.
What Lisp does is better, because it gives you
access to the source code in a form that's quite
easy for a program to work with. This makes it
much easier to write code that writes code, which
is what Lisp macros are all about.
(In most languages that have an interactive mode,
the printer *is* separated out in roughly the way
it is in Lisp.)
--
Gareth McCaughan
.sig under construc
From: Thomas Chatain
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <ciu5hv$82d$1@amma.irisa.fr>
By default, the reader converts every character to uppercase. That's why
you get:
* 'foo
FOO
* 'Foo
FOO
This behaviour of the lisp reader depends on the value of the readtable
case (see
<http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_23-1-2.html>).
You can set this value to :upcase (the default), :downcase, :preserve or
:invert as follows:
* (setf (readtable-case *readtable*) ':invert)
:invert
Now, you have:
* 'foo
foo
* 'Foo
Foo
If you use :preserve instead of :invert, you have to type almost
everything in uppercase, because the name of the usual functions is in
uppercase.
Just a final remark: IMHO it does not look very idiomatic in Lisp to
write function names with uppercase letters inside.
Thomas
Thanks a lot to all who answered. As I understand now it's more a
"visual" interpretation of a symbol by the reader. Internally the
symbols stays the same as defined.
Now I got another question. Why are the following pieces of code not
equivalent:
(setq sFunc "GetInputC")
(def-alien-routine sFunc void (fd integer) (param (* t)))
and:
(def-alien-routine "GetInputC" void (fd integer) (param (* t)))
As in the second case my cmucl interpreter doesn't fail as opposed to
the first case when it compains about the undefined function.
Thanks to all!
Andrew
Thomas Chatain <··············@irisa.fr> wrote in message news:<············@amma.irisa.fr>...
> By default, the reader converts every character to uppercase. That's why
> you get:
>
> * 'foo
> FOO
>
> * 'Foo
> FOO
>
> This behaviour of the lisp reader depends on the value of the readtable
> case (see
> <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_23-1-2.html>).
>
> You can set this value to :upcase (the default), :downcase, :preserve or
> :invert as follows:
>
> * (setf (readtable-case *readtable*) ':invert)
> :invert
>
> Now, you have:
>
> * 'foo
> foo
>
> * 'Foo
> Foo
>
> If you use :preserve instead of :invert, you have to type almost
> everything in uppercase, because the name of the usual functions is in
> uppercase.
>
> Just a final remark: IMHO it does not look very idiomatic in Lisp to
> write function names with uppercase letters inside.
>
> Thomas
·········@yahoo.com (Andrei) writes:
> Now I got another question. Why are the following pieces of code not
> equivalent:
>
> (setq sFunc "GetInputC")
> (def-alien-routine sFunc void (fd integer) (param (* t)))
>
> and:
> (def-alien-routine "GetInputC" void (fd integer) (param (* t)))
alien:def-alien-routine is a macro.
Here is part of its specification:
Define a foreign interface function for the routine with the
specified Name, which may be either a string, symbol or list of
the form (string symbol).
To see this, type (describe 'alien:def-alien-routine).
--
Fred Gilham ······@csl.sri.com
Comprehensive Computer Language Preference Survey
Do you like Lisp? (Check one)
[ ] Yes [ ] Sure [ ] You bet [ ] Yep [ ] Da
·········@yahoo.com (Andrei) writes:
> (setq sFunc "GetInputC")
> (def-alien-routine sFunc void (fd integer) (param (* t)))
>
> and:
> (def-alien-routine "GetInputC" void (fd integer) (param (* t)))
>
> As in the second case my cmucl interpreter doesn't fail as opposed to
> the first case when it compains about the undefined function.
Well, the macro (!) def-alien-routine does not evaluate the argument
naming the alien function. That is, instead of pulling out a value
from the binding of sFunc, it just uses the name of sFunc (that is,
SFUNC). In the second case it just uses the string.
I don't know what you are trying to do, but it smells like not the
right thing. Perhaps you would like to elaborate on your goals?
Finally, a nitpic. While cmucl includes an interpreter (two, actually,
IIRC), it also includes a full-fledged compiler.
Mario S. Mommer wrote:
> ·········@yahoo.com (Andrei) writes:
>
>>(setq sFunc "GetInputC")
>>(def-alien-routine sFunc void (fd integer) (param (* t)))
>>
>>and:
>>(def-alien-routine "GetInputC" void (fd integer) (param (* t)))
>>
>>As in the second case my cmucl interpreter doesn't fail as opposed to
>>the first case when it compains about the undefined function.
>
>
> Well, the macro (!) def-alien-routine does not evaluate the argument
> naming the alien function. That is, instead of pulling out a value
> from the binding of sFunc, it just uses the name of sFunc (that is,
> SFUNC). In the second case it just uses the string.
>
> I don't know what you are trying to do, but it smells like not the
> right thing. Perhaps you would like to elaborate on your goals?
Andrew seems to be looking for a quick way to toss off a bunch of FFI
definitions programmatically. Recall the original:
> Let's say I have a code:
>
> (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> (list (list 'S 1) 'SetInput)))
> (defun DefAlienFunc (assoclist)
> (if (not (null assoclist))
> (let ((sDefAlienFunc (format nil "~aC" (cadar assoclist))))
> (def-alien-routine sDefAlienFunc void (fd integer) (param (* t)))
> (DefAlienFunc (cdr assoclist)))))
>
> (DefAlienFunc *assoc-func*)
>
Thus Andrew is already lusting after the Unbearable Awesomeness of
Macros, albeit unwittingly. ie, He wants to write code which writes
code. This is necessary because def-alien-routine (I gather) is a macro
which does not evaluate the function name. So Andrew must write code
which prgrammatically works down *assoc-func* and writes individual
def-alien-routine forms for each entry.
In Andrew's situation I just cooked up a macro and typed it up for each
ffi entry, easing the task by globally editing a C header. To continue
with his original approach, we need something like the thoroughly
untested because merely typed-into-browser:
(defmacro def-alien-funcs (assoclist)
`(progn
,@(mapcar (lambda (assoc)
`(def-alien-routine
,(format nil "~aC" (cadr assoc))
void (fd integer) (param (* t))))
assoclist)))
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Kenny,
Thanks you ever so much for your close attention to my problem and
setting me on the path of exploring the macros!
What I did for now didn't wors as I type:
(def-alien-funcs *assoc-func*)
it says *ASSOC-FUNC* is not of type LIST.
I thought that theoretically if I define something simple like:
(defmacro def-alien-func (func-name)
`(def-alien-routine ,func-name void (fd integer) (param (* t))))
It would replace the evaluate func-name into a real string but no! :(
It tries to substitute func-name for the parameter I pass when I call
the macro.
Anyway, now I am going to explore the wonderful world of lisp macros
and hope to solve this problem. For now I solved it by calling:
(alien-funcall (extern-alien "SetInputC" (function void integer (*
t))) fd (addr InpVal)))) so I don't have to call def-alien-routine
prior to that but I don't consider it as a clean solution.
Thanks,
Andrew
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<······················@twister.nyc.rr.com>...
> Mario S. Mommer wrote:
> > ·········@yahoo.com (Andrei) writes:
> >
> >>(setq sFunc "GetInputC")
> >>(def-alien-routine sFunc void (fd integer) (param (* t)))
> >>
> >>and:
> >>(def-alien-routine "GetInputC" void (fd integer) (param (* t)))
> >>
> >>As in the second case my cmucl interpreter doesn't fail as opposed to
> >>the first case when it compains about the undefined function.
> >
> >
> > Well, the macro (!) def-alien-routine does not evaluate the argument
> > naming the alien function. That is, instead of pulling out a value
> > from the binding of sFunc, it just uses the name of sFunc (that is,
> > SFUNC). In the second case it just uses the string.
> >
> > I don't know what you are trying to do, but it smells like not the
> > right thing. Perhaps you would like to elaborate on your goals?
>
> Andrew seems to be looking for a quick way to toss off a bunch of FFI
> definitions programmatically. Recall the original:
>
> > Let's say I have a code:
> >
> > (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> > (list (list 'S 1) 'SetInput)))
> > (defun DefAlienFunc (assoclist)
> > (if (not (null assoclist))
> > (let ((sDefAlienFunc (format nil "~aC" (cadar assoclist))))
> > (def-alien-routine sDefAlienFunc void (fd integer) (param (* t)))
> > (DefAlienFunc (cdr assoclist)))))
> >
> > (DefAlienFunc *assoc-func*)
> >
>
> Thus Andrew is already lusting after the Unbearable Awesomeness of
> Macros, albeit unwittingly. ie, He wants to write code which writes
> code. This is necessary because def-alien-routine (I gather) is a macro
> which does not evaluate the function name. So Andrew must write code
> which prgrammatically works down *assoc-func* and writes individual
> def-alien-routine forms for each entry.
>
> In Andrew's situation I just cooked up a macro and typed it up for each
> ffi entry, easing the task by globally editing a C header. To continue
> with his original approach, we need something like the thoroughly
> untested because merely typed-into-browser:
>
> (defmacro def-alien-funcs (assoclist)
> `(progn
> ,@(mapcar (lambda (assoc)
> `(def-alien-routine
> ,(format nil "~aC" (cadr assoc))
> void (fd integer) (param (* t))))
> assoclist)))
>
> kenny
From: Kenny Tilton
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <4154B316.8090708@nyc.rr.com>
Andrei wrote:
> Kenny,
>
> Thanks you ever so much for your close attention to my problem and
> setting me on the path of exploring the macros!
>
> What I did for now didn't wors as I type:
> (def-alien-funcs *assoc-func*)
> it says *ASSOC-FUNC* is not of type LIST.
> I thought that theoretically if I define something simple like:
> (defmacro def-alien-func (func-name)
> `(def-alien-routine ,func-name void (fd integer) (param (* t))))
Ouch. I really screwed up! Let me try again:
This won't work: (def-alien-funcs *assoc-func*)
Well, maybe there is a sneaky way to make it work, but let's avoid
sneaky for now.
You have two choices:
(defmacro def-alien-funcs ()
`(progn
,@(mapcar (lambda (assoc)
`(def-alien-routine
,(format nil "~aC" (cadr assoc))
void (fd integer) (param (* t))))
*assoc-func*)))
Or my first offering (below) but used thus:
(def-alien-funcs
(((G 1) GetInput) ;; sorry, from memory
((S 1) SetInput)))
The first option is obviously less flexible.
I will use google to find your original and post a fuller, /tested/
solution. :)
kenny
>>(defmacro def-alien-funcs (assoclist)
>> `(progn
>> ,@(mapcar (lambda (assoc)
>> `(def-alien-routine
>> ,(format nil "~aC" (cadr assoc))
>> void (fd integer) (param (* t))))
>> assoclist)))
>>
>>kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Kenny Tilton wrote:
>
>
> Andrei wrote:
>
>> Kenny,
>>
>> Thanks you ever so much for your close attention to my problem and
>> setting me on the path of exploring the macros!
>>
>> What I did for now didn't wors as I type:
>> (def-alien-funcs *assoc-func*)
>> it says *ASSOC-FUNC* is not of type LIST.
>> I thought that theoretically if I define something simple like:
>> (defmacro def-alien-func (func-name)
>> `(def-alien-routine ,func-name void (fd integer) (param (* t))))
>
>
> Ouch. I really screwed up! Let me try again:
>
> This won't work: (def-alien-funcs *assoc-func*)
> Well, maybe there is a sneaky way to make it work, but let's avoid
> sneaky for now.
>
> You have two choices:
>
> (defmacro def-alien-funcs ()
> `(progn
> ,@(mapcar (lambda (assoc)
> `(def-alien-routine
> ,(format nil "~aC" (cadr assoc))
> void (fd integer) (param (* t))))
> *assoc-func*)))
>
> Or my first offering (below) but used thus:
>
> (def-alien-funcs
> (((G 1) GetInput) ;; sorry, from memory
> ((S 1) SetInput)))
>
> The first option is obviously less flexible.
>
> I will use google to find your original and post a fuller, /tested/
> solution. :)
>
(defmacro def-alien-funcs (alien-specs)
`(progn
,@(mapcar (lambda (alien-spec)
(destructuring-bind ((c n) c-name) alien-spec
(declare (ignore c n))
`(def-alien-routine
,(format nil "~aC" c-name)
void (fd integer) (param (* t)))))
alien-specs)))
#+test
(macroexpand-1
'(Def-Alien-Funcs
(((G 1) "GetInput")
((S 1) "SetInput"))))
=>
(PROGN (DEF-ALIEN-ROUTINE "GetInputC" VOID (FD INTEGER) (PARAM (* T)))
(DEF-ALIEN-ROUTINE "SetInputC" VOID (FD INTEGER) (PARAM (* T))))
If you do not need to control the case, you do not need the quotation
marks around "GetInput" etc. Same code works:
#+test
(macroexpand-1
'(Def-Alien-Funcs
(((G 1) GetInput)
((S 1) SetInput))))
=>
(PROGN (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
(DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T))))
Hopefully this is close enough to what you were after. Sorry again for
the misdirection.
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Kenny you are GREAT!
Both of you examples work and somehow I prefer the first one. It's
easier for me to understand and it reuses the already defined
*assoc-funcs* list. Though I still don't understand all the
intricacies of your examples it'll give me something to digest during
next week.
Andrew
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<·························@twister.nyc.rr.com>...
> Kenny Tilton wrote:
>
> >
> >
> > Andrei wrote:
> >
> >> Kenny,
> >>
> >> Thanks you ever so much for your close attention to my problem and
> >> setting me on the path of exploring the macros!
> >>
> >> What I did for now didn't wors as I type:
> >> (def-alien-funcs *assoc-func*)
> >> it says *ASSOC-FUNC* is not of type LIST.
> >> I thought that theoretically if I define something simple like:
> >> (defmacro def-alien-func (func-name)
> >> `(def-alien-routine ,func-name void (fd integer) (param (* t))))
> >
> >
> > Ouch. I really screwed up! Let me try again:
> >
> > This won't work: (def-alien-funcs *assoc-func*)
> > Well, maybe there is a sneaky way to make it work, but let's avoid
> > sneaky for now.
> >
> > You have two choices:
> >
> > (defmacro def-alien-funcs ()
> > `(progn
> > ,@(mapcar (lambda (assoc)
> > `(def-alien-routine
> > ,(format nil "~aC" (cadr assoc))
> > void (fd integer) (param (* t))))
> > *assoc-func*)))
> >
> > Or my first offering (below) but used thus:
> >
> > (def-alien-funcs
> > (((G 1) GetInput) ;; sorry, from memory
> > ((S 1) SetInput)))
> >
> > The first option is obviously less flexible.
> >
> > I will use google to find your original and post a fuller, /tested/
> > solution. :)
> >
>
>
> (defmacro def-alien-funcs (alien-specs)
> `(progn
> ,@(mapcar (lambda (alien-spec)
> (destructuring-bind ((c n) c-name) alien-spec
> (declare (ignore c n))
> `(def-alien-routine
> ,(format nil "~aC" c-name)
> void (fd integer) (param (* t)))))
> alien-specs)))
>
> #+test
> (macroexpand-1
> '(Def-Alien-Funcs
> (((G 1) "GetInput")
> ((S 1) "SetInput"))))
> =>
> (PROGN (DEF-ALIEN-ROUTINE "GetInputC" VOID (FD INTEGER) (PARAM (* T)))
> (DEF-ALIEN-ROUTINE "SetInputC" VOID (FD INTEGER) (PARAM (* T))))
>
> If you do not need to control the case, you do not need the quotation
> marks around "GetInput" etc. Same code works:
>
> #+test
> (macroexpand-1
> '(Def-Alien-Funcs
> (((G 1) GetInput)
> ((S 1) SetInput))))
> =>
> (PROGN (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
> (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T))))
>
>
> Hopefully this is close enough to what you were after. Sorry again for
> the misdirection.
>
> kenny
Andrei wrote:
> Both of you examples work and somehow I prefer the first one. It's
> easier for me to understand and it reuses the already defined
> *assoc-funcs* list.
OK, but then you have not added a reusable tool to your toolkit, because
the macro is hard-coded to work against one list. Well, you could rebind
the special *assoc-funcs* in the source and then reuse the macro, but
then things are starting to get a little perverse.
The sneaky way would be to have your macro take advantage of:
(defparameter *bb* 42)
(symbol-value '*bb*) => 42
but that too makes me queasy.
> Though I still don't understand all the
> intricacies of your examples it'll give me something to digest during
> next week.
The scary thing is that, since a macro is really just another Lisp
function, you can put print statements in the macro body to figure out
what is going on. Here is how one could have diagnosed my goofy original
offering (simplified):
(defmacro reversef (parm-vals)
(print (list 'inputs parm-vals (type-of parm-vals)
(symbol-value parm-vals)))
`(progn
,@(mapcar (lambda (parm-val)
(print `(parm-val ',parm-val))
`(defparameter ,(car parm-val),(cadr parm-val)))
(symbol-value parm-vals))))
(defparameter *bindings* '((a 1)(b 2)))
(macroexpand-1 '(reversef *bindings*))
=>
(INPUTS *BINDINGS* SYMBOL ((A 1) (B 2)))
(PARM-VAL '(A 1))
(PARM-VAL '(B 2))
(PROGN (DEFPARAMETER A 1) (DEFPARAMETER B 2))
The last line is simply the listener printing the value returned by the
macroexpansion. (It works because I used the sneaky trick I hinted at
earlier.)
But the first three lines after the macroexpansion form are my own
debugging statements, and reveal my gaffe: macros see code in symbolic
form, so in the orginal *assoc-list* came through not as the list of
desired alien funcs but simply as the symbol '*assoc-list*.
Macros are a big step up from vanilla Lisp, so (a) I would not be
concerned if they seem a little hairy and (b) remember that you can
debug them with print statements just like any other code. indeed, the
light bulb really went on for me when I saw the output of such
debugging, because at first I was really floored by some of the output.
kt
Thank you, Kenny
I started to read "On Lisp" by Paul Graham and home to get a hang of
macros soon.
What still bothers me is when I create a list like
(setq *assoc-func* (list (list (list 'G 1) 'GetInput)
(list (list 'S 1) 'SetInput)))
With:
(defmacro def-alien-funcs ()
`(progn
,@(mapcar (lambda (assoc)
`(def-alien-routine
,(format nil "~aC" (cadr assoc))
void (fd integer) (param (* t))))
*assoc-func*)))
I get an expanded program:
(PROGN
(DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
(DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
Which is not exactrly what I need because of "GETINPUTC".
With (setq *assoc-func2* (list (list (list 'G 1) "GetInput")
(list (list 'S 1) "SetInput")))
I get the correct result but I need 'GetInput (not a string) in order
to use it when I look for a lisp wrapper around GetInputC.
I tried to use |GetInput| and also played with (setf (readtable-case
*readtable*) ':invert) but it seem to coplicate things.
I wonder what's the background of the idea to read all the symbols in
"cap" case? Wouldn't it be more natural to leave them as they are?
Thanks,
Andrew
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<·····················@twister.nyc.rr.com>...
> Andrei wrote:
>
> > Both of you examples work and somehow I prefer the first one. It's
> > easier for me to understand and it reuses the already defined
> > *assoc-funcs* list.
>
> OK, but then you have not added a reusable tool to your toolkit, because
> the macro is hard-coded to work against one list. Well, you could rebind
> the special *assoc-funcs* in the source and then reuse the macro, but
> then things are starting to get a little perverse.
>
> The sneaky way would be to have your macro take advantage of:
>
> (defparameter *bb* 42)
> (symbol-value '*bb*) => 42
>
> but that too makes me queasy.
>
>
> > Though I still don't understand all the
> > intricacies of your examples it'll give me something to digest during
> > next week.
>
> The scary thing is that, since a macro is really just another Lisp
> function, you can put print statements in the macro body to figure out
> what is going on. Here is how one could have diagnosed my goofy original
> offering (simplified):
>
> (defmacro reversef (parm-vals)
> (print (list 'inputs parm-vals (type-of parm-vals)
> (symbol-value parm-vals)))
> `(progn
> ,@(mapcar (lambda (parm-val)
> (print `(parm-val ',parm-val))
> `(defparameter ,(car parm-val),(cadr parm-val)))
> (symbol-value parm-vals))))
>
> (defparameter *bindings* '((a 1)(b 2)))
>
> (macroexpand-1 '(reversef *bindings*))
> =>
> (INPUTS *BINDINGS* SYMBOL ((A 1) (B 2)))
> (PARM-VAL '(A 1))
> (PARM-VAL '(B 2))
> (PROGN (DEFPARAMETER A 1) (DEFPARAMETER B 2))
>
> The last line is simply the listener printing the value returned by the
> macroexpansion. (It works because I used the sneaky trick I hinted at
> earlier.)
>
> But the first three lines after the macroexpansion form are my own
> debugging statements, and reveal my gaffe: macros see code in symbolic
> form, so in the orginal *assoc-list* came through not as the list of
> desired alien funcs but simply as the symbol '*assoc-list*.
>
> Macros are a big step up from vanilla Lisp, so (a) I would not be
> concerned if they seem a little hairy and (b) remember that you can
> debug them with print statements just like any other code. indeed, the
> light bulb really went on for me when I saw the output of such
> debugging, because at first I was really floored by some of the output.
>
> kt
Andrei wrote:
> Thank you, Kenny
>
> I started to read "On Lisp" by Paul Graham and home to get a hang of
> macros soon.
> What still bothers me is when I create a list like
> (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> (list (list 'S 1) 'SetInput)))
> With:
> (defmacro def-alien-funcs ()
> `(progn
> ,@(mapcar (lambda (assoc)
> `(def-alien-routine
> ,(format nil "~aC" (cadr assoc))
> void (fd integer) (param (* t))))
> *assoc-func*)))
>
> I get an expanded program:
> (PROGN
> (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
> (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
>
> Which is not exactrly what I need because of "GETINPUTC".
>
> With (setq *assoc-func2* (list (list (list 'G 1) "GetInput")
> (list (list 'S 1) "SetInput")))
>
> I get the correct result but I need 'GetInput (not a string) in order
> to use it when I look for a lisp wrapper around GetInputC.
If you explain this with a code snippet which shows what you would like
to work but does not, we can probably get it working for you. Might be
as simple as a little more macrology. :)
You might find a solution yourself if you play around with symbol-name
and (concatenate 'string ...) and case-insensitive string comparators,
etc etc. But just psot the problem if it seems too hairy.
>
> I tried to use |GetInput| and also played with (setf (readtable-case
> *readtable*) ':invert) but it seem to coplicate things.
> I wonder what's the background of the idea to read all the symbols in
> "cap" case? Wouldn't it be more natural to leave them as they are?
Good question. Ping the historians. I have only been on board for ten
years, still a newby myself.
Maybe "Back In the Day" they were not worried about talking to other
languages, including case-sensitive languages. And I must say as a weak
typist who has written tons of C that case-insensitivty is a lot more
relaxing.
Note also that AllegroCL has a modern mode which (I think!) is case
sensitive, precisely because (I guess!) Lispniks now realize the Outside
World must be dealt with if Lisp is to grow.
kenny
Kenny Tilton <·······@nyc.rr.com> wrote:
+---------------
| Andrei wrote:
| > I wonder what's the background of the idea to read all the symbols in
| > "cap" case? Wouldn't it be more natural to leave them as they are?
|
| Good question. Ping the historians. I have only been on board for ten
| years, still a newby myself.
| Maybe "Back In the Day" they were not worried about talking to other
| languages, including case-sensitive languages...
+---------------
Actually, I suspect it was the Teletype Model ASR33 (sometimes called the
Model 33 ASR), manufactured by the Teletype Corporation of Skokie, Ill.,
that was the basis for the problem. (Google for "teletype skokie asr33"
for lots & lots of history.) ;-} ;-}
Even though they used "8-level" ASCII (7-bits plus parity), they were
upper-case only. They responded to lower-case alphabetics by printing
the corresponding upper-case character, but the keyboard generated upper
case only. These machines were the workhorse terminals of their day,
and many operating systems were written on the assumption that their
consoles and remote terminals were ASR33s (or compatible). Even when
"glass TTYs" ["TTY" is a contraction of "teletypewriter] or "video
terminals" started to become available, the very first ones were also
upper-case only.
The later (and more expensive!) ASR37, on the other hand, was an upper-
and lower-case terminal (though still almost entirely mechanical, like
the ASR33). Quite prized for document text entry, it created a problem
for operating systems that assumed commands were uppercase-only. So the
solution was to map lowercase input characters to uppercase internally
when needed.
[Operating systems written much later, such as Unix, had to deal with
the opposite problem: Having mixed-case as the default, and having the
standard commands expecting lowercase, how to deal with those users who
still had only uppercase-only terminal? See "stty(1)" for the "iuclc"
and "xcase" terminal options.]
So I suspect that Lisp (or LISP, as it was spelled back then) grew up
in a time when uppercase-only terminals were still more common than
lowercase-capable ones.
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <ulleudgco.fsf@news.dtpq.com>
····@rpw3.org (Rob Warnock) writes:
> Kenny Tilton <·······@nyc.rr.com> wrote:
> +---------------
> | Andrei wrote:
> | > I wonder what's the background of the idea to read all the symbols in
> | > "cap" case? Wouldn't it be more natural to leave them as they are?
> |
> | Good question. Ping the historians. I have only been on board for ten
> | years, still a newby myself.
> | Maybe "Back In the Day" they were not worried about talking to other
> | languages, including case-sensitive languages...
> +---------------
>
> Actually, I suspect it was the Teletype Model ASR33
Case sensitive languages? Surely you jest.
Have you ever wondered why the source code that you sometimes
see for very early LISP programs was not written with the nice
indentation that we favor today? Even though the handwritten
M-exprs are usually pretty like mathematical notations?
Here's a hint, kiddies: The original character set for Lisp was
what was available on the IBM 026 keypunch (for punched cards).
I don't know when LISP was first used with a typewriter device.
It could have been pretty early on. But punched cards and paper
tape were more common. Interactive computing was very uncommon.
I don't think the IBM 704 or 709 even had a typewriter option.
Regarding the ASR-33 teletype...that's some newfangled terminal
using, what's it called...ASCII? No, don't think so, not on IBM.
And the typewriter input devices on the IBM computers (like the 7090)
were more primitive than that. A little later on at Project MAC,
there were IBM 1050 Selectric typewriters, though. I think CTSS
also supported ASR-35s. The DEC PDP-1 machines could (and did)
have both Selectric and ASR-33 terminals.
As to why this was uppercaseness was never fixed: It Ain't Broke!
Why shouldn't the representation of symbols be uppercase?
And I think it's useful to remind beginners that what they see on
the terminal is not actually their Lisp code. seeing that their
input is converted into something else highlights this difference
from character-based languages. Anyway, there is no need at all for
mixed case if all you have is symbols. When I started programming
in MACLISP around 1980, it didn't even have strings. (There were some
gross hacks for pretend strings; you could make lowercase symbols.)
Uppercase only looks strange if you're used to lowercase. It still
looked perfectly reasonable even in 1980, even though most terminals
(except ASR-33s) had lowercase by then. The other languages, FORTRAN
and COBOL and BASIC and SNOBOL and APL and so on were all uppercase.
You don't need lowercase unless you're trying to have a fancy UI.
Back then, LISP was used exclusively for AI, and such fancy interfaces
were not really important. These things all changed as the Lisp
Machines came along.
In some Lisp implementations, you can set a variable that will make
symbols print out in lowercase, if it really bothers you. With all
the graphical interfaces around today, I still don't notice that my
code prints out in uppercase, but maybe I'm just old fashioned that way.
Today I do _write_ my code in lowercase, though I used to usually
elect to write in uppercase until late 1983 (based on some very
old programs of mine that I just now wandered around looking at).
Hi Christopher C. Stacy,
> As to why this was uppercaseness was never fixed: It Ain't Broke!
It's suboptimal, but we're stuck with the legacy. I've used it to play a
few tricks, e.g. using |...| as an abbreviation for length. curve and
|curve| ("length of curve") are different symbols in both default and
invert reader modes ;-)
> Why shouldn't the representation of symbols be uppercase?
Because (a) it forces unnecessary consing between the character
representation and the symbol name; and (b) using invert mode, which
is necessary to preserve case sensitivity, imposes a psychic cost in
addition to the programming overhead of explicit string inverts.
Also, fully conforming Unicode case inversion is very complicated and
locale specific. It is best avoided in any internal code representation
(s-expressions).
It is possible to avoid the ongoing overhead of string inverting if one
can spare the resources to cache the results:
(defun string-invert (string)
(declare (optimize (speed 3) (compilation-speed 0) (debug 0) (safety 0))
(string string))
(let (up down)
(loop for char of-type character across string do
(cond ((upper-case-p char)
(if down (return-from string-invert string) (setf up t)))
((lower-case-p char)
(if up (return-from string-invert string) (setf down t)))))
(if up (string-downcase string) (string-upcase string))))
(let ((package-table (make-hash-table :test #'eq)))
(defun invert&intern (string &optional (package *package*))
"Interned inverted results are cached per symbol per package, eliminating
inverting overhead after the symbol is first interned."
(declare (optimize (speed 3) (compilation-speed 0) (debug 0) (safety 0))
(string string))
(let ((string->symbol-table (gethash package package-table)))
(unless string->symbol-table
(setf (gethash package package-table) (make-hash-table :test #'equal))
(setf string->symbol-table (gethash package package-table)))
(multiple-value-bind (value present)
(gethash string string->symbol-table)
(if present
value
(let ((interned (intern (string-invert string) package)))
(setf (gethash string string->symbol-table) interned)
interned))))))
> And I think it's useful to remind beginners that what they see on
> the terminal is not actually their Lisp code. seeing that their
> input is converted into something else highlights this difference
> from character-based languages.
This is not a worthy design goal for Common Lisp and it would be abandoned
in a second if it wasn't for the issue with legacy code.
(snipped interesting history)
> In some Lisp implementations, you can set a variable that will make
> symbols print out in lowercase, if it really bothers you.
All conforming implementations support the readtable invert mode:
(setf (readtable-case *readtable*) :invert)
Regards,
Adam
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <u655ygsav.fsf@news.dtpq.com>
Adam Warner <······@consulting.net.nz> writes:
> Hi Christopher C. Stacy,
>
> > Why shouldn't the representation of symbols be uppercase?
>
> Because (a) it forces unnecessary consing between the character
> representation and the symbol name;
Uppercasing a character upon input does not require any heap allocation.
> (b) using invert mode, which is necessary to preserve case
> sensitivity, imposes a psychic cost in addition to the
> programming overhead of explicit string inverts.
Good reason not to use the :INVERT hack, I suppose,
but I can't quite tell what you're complaining about.
This part of the Lisp system (the READ function) has
already been written for you.
> Also, fully conforming Unicode case inversion is very complicated and
> locale specific. It is best avoided in any internal code representation
> (s-expressions).
The Lisp character set (for code) is not Unicode.
As far as I can tell, your issues stem from wanting to use Unicode
characters in symbol names. Lisp doesn't have that. (I don't know
of any other programming languages that have it, either.)
(Whether Lisp can manipulate strings of Uniode is unrelated, of course.)
From: Peter Seibel
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <m3vfdydwit.fsf@javamonkey.com>
······@news.dtpq.com (Christopher C. Stacy) writes:
> As far as I can tell, your issues stem from wanting to use Unicode
> characters in symbol names. Lisp doesn't have that. (I don't know of
> any other programming languages that have it, either.)
Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <uvfdyp2o1.fsf@news.dtpq.com>
Peter Seibel <·····@javamonkey.com> writes:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
> > As far as I can tell, your issues stem from wanting to use Unicode
> > characters in symbol names. Lisp doesn't have that. (I don't know of
> > any other programming languages that have it, either.)
>
> Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
Oh.
······@news.dtpq.com (Christopher C. Stacy) writes:
> Peter Seibel <·····@javamonkey.com> writes:
>
>> ······@news.dtpq.com (Christopher C. Stacy) writes:
>>
>> > As far as I can tell, your issues stem from wanting to use Unicode
>> > characters in symbol names. Lisp doesn't have that. (I don't know of
>> > any other programming languages that have it, either.)
>>
>> Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
>
> Oh.
http://clisp.sourceforge.net/fibjap-xterm.png
What am I missing?
Regards,
--
____________________________
Julian Stecklina / _________________________/
________________/ /
\_________________/ LISP - truly beautiful
Julian Stecklina wrote:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
>
>>Peter Seibel <·····@javamonkey.com> writes:
>>
>>
>>>······@news.dtpq.com (Christopher C. Stacy) writes:
>>>
>>>
>>>>As far as I can tell, your issues stem from wanting to use Unicode
>>>>characters in symbol names. Lisp doesn't have that. (I don't know of
>>>>any other programming languages that have it, either.)
>>>
>>>Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
>>
>>Oh.
>
>
> http://clisp.sourceforge.net/fibjap-xterm.png
>
> What am I missing?
A standard?
Cheers
--
Marco
Peter Seibel <·····@javamonkey.com> writes:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
>> As far as I can tell, your issues stem from wanting to use Unicode
>> characters in symbol names. Lisp doesn't have that. (I don't know of
>> any other programming languages that have it, either.)
>
> Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
Emacs Lisp as well.
--
Jesper Harder <http://purl.org/harder/>
Peter Seibel wrote:
>
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
> > As far as I can tell, your issues stem from wanting to use Unicode
> > characters in symbol names. Lisp doesn't have that. (I don't know of
> > any other programming languages that have it, either.)
>
> Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
>
Interlisp-D did, ca. 1985, continuing the tradition of "Lisp was there
first".
- Bob
Hi Peter Seibel,
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
>> As far as I can tell, your issues stem from wanting to use Unicode
>> characters in symbol names. Lisp doesn't have that. (I don't know of
>> any other programming languages that have it, either.)
>
> Java, C#, and Perl (as of some version >= 5.6.<mumble>) do.
Java and C# (I don't know about Perl) at their language core (primitives)
have poor Unicode support. Java was designed at a time when Unicode code
points fitted within 16-bit values (that's why char is defined as unsigned
16-bit). C#, being Microsoft's copy of Java, perpetrated the mistake many
years later.
UTF-16 encoding, necessary to support all Unicode code points, is a
terrible kludge that has forced the Unicode code space to be limited to
2^20+2^16 code points _for all time_. A naive binary sort also sorts
code points incorrectly (unlike UTF-8 and UTF-32).
These languages only work acceptably with Unicode because of the higher
level APIs. 8- or 32-bit character primitives are a better foundation for
a Unicode-supporting computer language. I have no problem working with
Unicode strings in CMUCL/SBCL because of Unix's 8-bit character legacy. To
support Unicode fully you have to start working with variable length
characters anyway (even in UTF-32 because of, e.g., combining characters).
A future Unicode aware Common Lisp standard would have trouble defining an
:INVERT mode for preserving case because there is no 1-1 mapping between
lowercase and uppercase characters. What is the invert of the surname of a
participant in this forum, FRANK BUSS? Is it "buss" or is it "buß"? Which
one it is depends upon knowledge of the language the symbol was written in.
Common Lisp should leave the case of symbols alone. It's an ASCII centric
legacy and a mistake.
Regards,
Adam
···@zedat.fu-berlin.de (Stefan Ram) writes:
> [...]
> The letter "�" never starts a word. For this reason, an
> uppercase "�" is never needed
There must be another reason, no? For example, CYRILLIC LETTER SOFT
SIGN never starts a word, yet there is a CAPITAL C.L.S.S. (Writing
in all capitals is not so uncommon in languages that use the
Cyrillic alphabet.)
* * *
There are significant differences between natural languages in the
treatment of letter case (even in the existence of that notion, for
that matter). I would conjecture that if a single definition of the
concept of case, and the concept of case conversion, is produced in
such a way that it fits all the natural languages in the world, then
this definition would be so very general that it would not be very
useful. (By the way, in the history of writing, letter case is a
relatively new invention.)
Even if the restrictions of the I/O devices of the 1950s and 1960s
are the only reason why Lisp symbols' names are (by default)
case-insensitive, I have always thought that this also matches the
property of many natural languages to treat, for example, "John Doe"
and "JOHN DOE" as equivalent names. Yes, it is true that having
case-insensitive Lisp symbol names leads to trouble if we try to use
the whole of Unicode for those names, but is the latter _really_
such a good idea? After all, trying to write English with Cyrillic
letters also spells trouble, if I may use a flamable analogy...
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
Hi Vassil Nikolov,
> Even if the restrictions of the I/O devices of the 1950s and 1960s
> are the only reason why Lisp symbols' names are (by default)
> case-insensitive, I have always thought that this also matches the
> property of many natural languages to treat, for example, "John Doe"
> and "JOHN DOE" as equivalent names. Yes, it is true that having
> case-insensitive Lisp symbol names leads to trouble if we try to use
> the whole of Unicode for those names, but is the latter _really_
> such a good idea? After all, trying to write English with Cyrillic
> letters also spells trouble, if I may use a flamable analogy...
WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
while sitting on the john at the DOE John Doe saw a doe
(Interpretation: While sitting on the toilet at the Department of Energy,
John Doe saw a female deer).
In this example critical information is thrown by uppercasing the
symbols.
Regards,
Adam
Hi Vassil Nikolov,
> Even if the restrictions of the I/O devices of the 1950s and 1960s
> are the only reason why Lisp symbols' names are (by default)
> case-insensitive, I have always thought that this also matches the
> property of many natural languages to treat, for example, "John Doe"
> and "JOHN DOE" as equivalent names. Yes, it is true that having
> case-insensitive Lisp symbol names leads to trouble if we try to use
> the whole of Unicode for those names, but is the latter _really_
> such a good idea? After all, trying to write English with Cyrillic
> letters also spells trouble, if I may use a flamable analogy...
WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
while sitting on the john at the DOE John Doe saw a doe
(Interpretation: While sitting on the toilet at the Department of Energy,
John Doe saw a female deer).
In this example critical information is thrown away by uppercasing the
character representations.
Regards,
Adam
Adam Warner <······@consulting.net.nz> writes:
> Hi Vassil Nikolov,
>
>> Even if the restrictions of the I/O devices of the 1950s and 1960s
>> are the only reason why Lisp symbols' names are (by default)
>> case-insensitive, I have always thought that this also matches the
>> property of many natural languages to treat, for example, "John Doe"
>> and "JOHN DOE" as equivalent names. Yes, it is true that having
>> case-insensitive Lisp symbol names leads to trouble if we try to use
>> the whole of Unicode for those names, but is the latter _really_
>> such a good idea? After all, trying to write English with Cyrillic
>> letters also spells trouble, if I may use a flamable analogy...
>
> WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
>
> while sitting on the john at the DOE John Doe saw a doe
>
> (Interpretation: While sitting on the toilet at the Department of Energy,
> John Doe saw a female deer).
>
> In this example critical information is thrown away by uppercasing the
> character representations.
However, it is an example about something else. The point I was
trying to made was that, as long as it is known that "John Doe" and
"JOHN DOE" (or, say, "Abc Xyz" and "ABC XYZ") are proper names, then
they are equivalent (at least according to common usage in
English-speaking countries).
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
Hi Vassil Nikolov,
> However, it is an example about something else. The point I was
> trying to made was that, as long as it is known that "John Doe" and
> "JOHN DOE" (or, say, "Abc Xyz" and "ABC XYZ") are proper names, then
> they are equivalent (at least according to common usage in
> English-speaking countries).
OK. You still have to be careful how you input the symbol |JOHN DOE|.
(eq 'John\ Doe 'JOHN\ DOE) is true but you may be more likely to use
vertical bars and (eq '|John Doe| '|JOHN DOE|) is of course false.
How are you supposed to know the symbol denotes a proper name? Is it
because it is in a list that only contains proper names? Is it because
you've added the information to the symbol's property list? Or is it
because you only intern symbols with proper names within a particular
package?
This feels like a misuse of symbols. It would be better to create an
object with the type proper-name and a slot to hold the string name. Then
use an appropriate predicate to test for proper name equivalence. I'd try
to avoid using the reader as a surrogate for an EQUALP predicate.
Regards,
Adam
From: Christopher C. Stacy
Subject: Re: mappings between uppercase and lowercase
Date:
Message-ID: <ud605w0a8.fsf@news.dtpq.com>
Adam Warner <······@consulting.net.nz> writes:
> WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
> How are you supposed to know the symbol denotes a proper name? Is it
Symbols do not provide in themselves provide information;
they are more primitive than that. For a natural language
application like you are proposing, I would expect the input
to be a mixed-case string, and the output to be some directed
graph data that may or may not use symbols at all.
If it did use symbols, it might construct them with mixed case.
But nobody has used symbols for an input format as you are
proposing here since about 1980 (when strings came along).
So I don't see this is a real issue.
Adam Warner <······@consulting.net.nz> writes:
> Hi Vassil Nikolov,
>
>> However, it is an example about something else. The point I was
>> trying to made was that, as long as it is known that "John Doe" and
>> "JOHN DOE" (or, say, "Abc Xyz" and "ABC XYZ") are proper names, then
>> they are equivalent (at least according to common usage in
>> English-speaking countries).
>
> OK. You still have to be careful how you input the symbol |JOHN DOE|.
> (eq 'John\ Doe 'JOHN\ DOE) is true but you may be more likely to use
> vertical bars and (eq '|John Doe| '|JOHN DOE|) is of course false.
>
> How are you supposed to know the symbol denotes a proper name? Is it
> because it is in a list that only contains proper names? Is it because
> you've added the information to the symbol's property list? Or is it
> because you only intern symbols with proper names within a particular
> package?
>
> This feels like a misuse of symbols. It would be better to create an
> object with the type proper-name and a slot to hold the string name. Then
> use an appropriate predicate to test for proper name equivalence. I'd try
> to avoid using the reader as a surrogate for an EQUALP predicate.
It is a quite different point that I am trying to make, that is:
In at least a number of countries and natural languages, proper
names are case-insensitive. (E.g., if the context is the same, an
occurrence of "John Doe" would refer to the same person(s) as an
occurrence of "JOHN DOE".)
The (default) case insensitivity of Common Lisp symbol names
matches the above property of natural language usage, even if
originally the sole reason for that insensitivity were the
limitations of the I/O devices of the time.
I believe that having this property or not is an important aspect of
languages, programming languages included, and I don't believe it is
possible to achieve it in a programming language in a reasonable way
that is equally "culturally compatible" with all natural language
usage in the world. (So some tradeoff has to be made, like being
compatible with that usage in only some of the languages of the
world.)
(And the point I am trying to make is not at all about choosing Lisp
data types and structures to represent proper names from natural
languages.)
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
Hi Vassil Nikolov,
> It is a quite different point that I am trying to make, that is:
>
> In at least a number of countries and natural languages, proper
> names are case-insensitive. (E.g., if the context is the same, an
> occurrence of "John Doe" would refer to the same person(s) as an
> occurrence of "JOHN DOE".)
I have a greater appreciation for your point VASSIL NIKOLOV. Thank you for
your persistence.
Regards,
Adam
Adam Warner <······@consulting.net.nz> writes:
> Hi Vassil Nikolov,
>
>> It is a quite different point that I am trying to make, that is:
>>
>> In at least a number of countries and natural languages, proper
>> names are case-insensitive. (E.g., if the context is the same, an
>> occurrence of "John Doe" would refer to the same person(s) as an
>> occurrence of "JOHN DOE".)
>
> I have a greater appreciation for your point VASSIL NIKOLOV. Thank you for
> your persistence.
Who's VASSIL NIKOLOV?
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Patrick O'Donnell
Subject: Re: mappings between uppercase and lowercase
Date:
Message-ID: <rtbrfp10un.fsf@ascent.com>
Adam Warner <······@consulting.net.nz> writes:
> WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
>
> while sitting on the john at the DOE John Doe saw a doe
>
> (Interpretation: While sitting on the toilet at the Department of Energy,
> John Doe saw a female deer).
>
> In this example critical information is thrown away by uppercasing the
> character representations.
I disagree. Critical information is thrown away by taking the
utterance out of context. How do I know that John was at the
Department of Energy and not the Department of Education or the
Director of Engineering's office?
Capitalizing proper names is a typographical convention, not a
semantic one. Proper names are capitalized because they are proper
names; they are not proper names because they are capitalized.
Adam Warner <······@consulting.net.nz> writes:
> Hi Vassil Nikolov,
>
> > Even if the restrictions of the I/O devices of the 1950s and 1960s
> > are the only reason why Lisp symbols' names are (by default)
> > case-insensitive, I have always thought that this also matches the
> > property of many natural languages to treat, for example, "John Doe"
> > and "JOHN DOE" as equivalent names. Yes, it is true that having
> > case-insensitive Lisp symbol names leads to trouble if we try to use
> > the whole of Unicode for those names, but is the latter _really_
> > such a good idea? After all, trying to write English with Cyrillic
> > letters also spells trouble, if I may use a flamable analogy...
>
> WHILE SITTING ON THE JOHN AT THE DOE JOHN DOE SAW A DOE
>
> while sitting on the john at the DOE John Doe saw a doe
>
> (Interpretation: While sitting on the toilet at the Department of Energy,
> John Doe saw a female deer).
>
> In this example critical information is thrown away by uppercasing the
> character representations.
This is not "critical" information. This is pure syntactic
information. And unfortunately, unless it comes from a programmer
with a good compiler, syntactic information is useless or
contradictory. Just try to parse real HTML found on the web in a pure
syntactic (or even gramatical!) way. And we don't even mention here
natural language.
What if a case-impaired person (ie. a normal person) had written this:
WHILE sitting on the John at the doe john DOE saw a dOe.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
Adam Warner <······@consulting.net.nz> writes:
> Common Lisp should leave the case of symbols alone. It's an ASCII centric
> legacy and a mistake.
Then, why don't you just set your READTABLE-CASE to :PRESERVE and
leave us alone!
<plug shameless=yes>Do you know my upcase-lisp and upcase-lisp-region
emacs commands?</plug>
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
Hi Pascal Bourguignon,
>> Java and C# (I don't know about Perl) at their language core
>> (primitives) have poor Unicode support. Java was designed at a time
>> when Unicode code points fitted within 16-bit values (that's why char
>> is defined as unsigned 16-bit). C#, being Microsoft's copy of Java,
>> perpetrated the mistake many years later.
>>
>> UTF-16 encoding, necessary to support all Unicode code points, is a
>> terrible kludge that has forced the Unicode code space to be limited to
>> 2^20+2^16 code points _for all time_. A naive binary sort also sorts
>> code points incorrectly (unlike UTF-8 and UTF-32).
>>
>> These languages only work acceptably with Unicode because of the higher
>> level APIs. 8- or 32-bit character primitives are a better foundation
>> for a Unicode-supporting computer language. I have no problem working
>> with Unicode strings in CMUCL/SBCL because of Unix's 8-bit character
>> legacy. To support Unicode fully you have to start working with
>> variable length characters anyway (even in UTF-32 because of, e.g.,
>> combining characters).
>>
>> A future Unicode aware Common Lisp standard would have trouble defining
>> an :INVERT mode for preserving case because there is no 1-1 mapping
>> between lowercase and uppercase characters. What is the invert of the
>> surname of a participant in this forum, FRANK BUSS? Is it "buss" or is
>> it "buß"? Which one it is depends upon knowledge of the language the
>> symbol was written in.
>>
>> Common Lisp should leave the case of symbols alone. It's an ASCII
>> centric legacy and a mistake.
>
> Then, why don't you just set your READTABLE-CASE to :PRESERVE and leave
> us alone!
Leave what group alone? This newsgroup is not uncivil. And you don't
speak for it.
> <plug shameless=yes>Do you know my upcase-lisp and upcase-lisp-region
> emacs commands?</plug>
Apart from uppercase Common Lisp source looking butt ugly and shouting at
the reader and no source library written in lowercase even loading I can't
see any potential pitfalls.
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <uekklvjfv.fsf@news.dtpq.com>
Adam Warner <······@consulting.net.nz> writes:
> Apart from uppercase Common Lisp source looking butt ugly
That's just your opinion, of course; I don't think uppercase Lisp
source code looks ugly. I (and most people) used to choose to write
in all uppercase, long after lowercase terminals were commonplace.
Over the years I've changed my mind about my preference, and now
I write in lowercase, but it's just a personal aesthetic.
But when are you looking at the uppercase printed representation
of code, anyway? Certainly not in source code files.
I only see uppercase when I am interacting with a read-eval-print
loop of some sort, and I still like the fact that it prints out
in uppercase; it helps visually distinguish my typing from the
debugger output. (I think this is just like how some people like
to use colors and fonts for that sort of thing, and I know I'm not
alone in hating those.)
Hi Christopher C. Stacy,
> Adam Warner <······@consulting.net.nz> writes:
>> Apart from uppercase Common Lisp source looking butt ugly
>
> That's just your opinion, of course; I don't think uppercase Lisp
> source code looks ugly. I (and most people) used to choose to write
> in all uppercase, long after lowercase terminals were commonplace.
> Over the years I've changed my mind about my preference, and now
> I write in lowercase, but it's just a personal aesthetic.
WHAT ABOUT MY FOLLOWING COMMENT..."SHOUTING AT THE READER"? A REPLY IN
UPPERCASE IN USENET IS INFERRED TO MEAN THAT YOU ARE SHOUTING. THIS ISN'T
JUST MY OPINION. IT IS A SOCIAL CONVENTION.
IF THIS IS A CONVENTION YOU'VE LIVED WITH FOR MANY YEARS ALL UPPERCASE
SOURCE CODE CAN FEEL LIKE IT'S SHOUTING.
(I apologise for shouting!)
> But when are you looking at the uppercase printed representation
> of code, anyway? Certainly not in source code files.
If I set the readtable to :PRESERVE in ANSI Common Lisp, as I was told in
no uncertain terms to do, then all symbols in the COMMON-LISP package
would have to be input in uppercase:
CL-USER(1): (setf (readtable-case *readtable*) :preserve)
:PRESERVE
CL-USER(2): (setf (readtable-case *readtable*) :upcase)
Debugger invoked on condition of type UNDEFINED-FUNCTION:
The function setf is undefined.
Restarts:
0: TOP-LEVEL Return to top level.
[1] CL-USER(3): 0
CL-USER(4): (SETF (READTABLE-CASE *READTABLE*) :UPCASE)
:UPCASE
Hence my comment.
Regards,
Adam
Adam Warner <······@consulting.net.nz> writes:
> [...]
> IF THIS IS A CONVENTION YOU'VE LIVED WITH FOR MANY YEARS ALL UPPERCASE
> SOURCE CODE CAN FEEL LIKE IT'S SHOUTING.
I think it would be an interesting piece of research to find out
what is the actual proportion of programmers for whom it feels like
that. It may indeed be many---I can't say---but that is not
obvious. (For anecdotal evidence, while for me natural language in
all capitals certainly feels like shouting (or legally disclaiming
something), programming language doesn't (and I have done some,
though not much).)
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
From: ·········@cern.ch
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <yzo4qlhwfeb.fsf@cern.ch>
>>>>> "Adam" == Adam Warner <······@consulting.net.nz> writes:
Adam> (...)
Adam> (I apologise for shouting!)
Please try (SETQ *PRINT-CASE* :DOWNCASE), and stop shouting;-)
Ole
Hi Stefan Ram,
>>What is the invert of the surname of a participant in this
>>forum, FRANK BUSS? Is it "buss" or is it "buß"? Which one it is
>>depends upon knowledge of the language the symbol was written
>>in.
>
> Even if it is given that the language of "BUSS" is "de"
> (German), this can not be deduced. The lowercase version might
> be "buß" or "buss".
>
> However, according to the rules of the language, the spelling
> "BUSS" or "buss" is wrong. The correct spelling has to be
> "Buss" or "Buß". "BUSS" would indicate an acronym or
> initialism; and "B.U.S.S" would indicate an abreviation.
>
> The letter "ß" never starts a word. For this reason, an
> uppercase "ß" is never needed, when the rules of the language
> are applied strictly, because they do not allow uppercase
> letters inside a word, unless it is an initialism. In the
> case of an initialism, however, the "ß" would need to be
> that start of a word that the initialism is built from,
> which also is not possible.
>
> But when someone wants to enforce capitals, both "ss" and
> "ß" are converted to "SS". This mapping is not injective.
Thank you for the corrections and clarifications Stefan. All these issues
disappear if symbols are interned using their source representation. I
believe it's better to only perform case manipulations upon strings, where
more refined (and computationally expensive) tests for equality are
appropriate.
By default ANSI Common Lisp will intern the symbol Buss as BUSS. As you
state, according to the rules of German this spelling is incorrect. It
would not be if the source representation of the symbol was preserved.
Regards,
Adam
Adam Warner <······@consulting.net.nz> writes:
> [...]
> By default ANSI Common Lisp will intern the symbol Buss as BUSS. As [Stefan Ram]
> state[s], according to the rules of German this spelling is incorrect.
I think a fundamental question here is, are the rules of any natural
language relevant to the way the Lisp reader processes symbols, and
if yes, then which natural language would that be. (In my opinion,
it is appropriate for Lisp to be culturally compatible with
English.)
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
Stefan Ram wrote:
> The source used is page 83 of the book:
>
> [resource:book/Duden Rechtschreibung 1973] =
Did Germany change the Rechtshreibung rules in the
late 90's?
--
Jens Axel Søgaard
On Wed, 29 Sep 2004 12:55:30 +0200, Jens Axel S�gaard <······@soegaard.net> wrote:
> Did Germany change the Rechtshreibung rules in the late 90's?
Yes, but as Stefan wrote this is still not settled. A lot of people
(including well-known authors like Nobel laureate G�nter Grass) oppose
the new rules. Some of the biggest newspapers and magazines (ranging
from very respected ones like "Frankfurter Allgemeine Zeitung" or
"Spiegel" to tabloids like "Bild") either never used the new rules or
recently announced to switch back to the old ones.
Cheers,
Edi.
--
"Lisp doesn't look any deader than usual to me."
(David Thornley, reply to a question older than most languages)
Real email: (replace (subseq ·········@agharta.de" 5) "edi")
Edi Weitz wrote:
> On Wed, 29 Sep 2004 12:55:30 +0200, Jens Axel Søgaard <······@soegaard.net> wrote:
>>Did Germany change the Rechtshreibung rules in the late 90's?
> Yes, but as Stefan wrote this is still not settled. A lot of people
> (including well-known authors like Nobel laureate Günter Grass) oppose
> the new rules. Some of the biggest newspapers and magazines (ranging
> from very respected ones like "Frankfurter Allgemeine Zeitung" or
> "Spiegel" to tabloids like "Bild") either never used the new rules or
> recently announced to switch back to the old ones.
I recognize that story. We changed the comma rules 10 years ago. We had
two systems a grammatical one (used by 95%) and a use-commas-as-pauses
system. The pause system were abolished and then one could choose between
two grammatical systems: the old one, and "the new comma".
Most people have a hard time learning comma systems, so news papers and
books kept using the old one. Then two years the comma war started again.
This forced the "council" to remove the new system. However, they made
a twist to the old system. They made some of the commas optional. In effect
one can keep using the new system - but the the old commatist are now happy.
--
Jens Axel Søgaard
From: Christophe Rhodes
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <sqekkm9ky4.fsf@cam.ac.uk>
······@news.dtpq.com (Christopher C. Stacy) writes:
> The Lisp character set (for code) is not Unicode.
Isn't the Lisp character set for code the character set supported by
the implementation? For conforming code, one should only use standard
characters of course (I hope no-one here has tabs in their source
code).
Christophe
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <umzzaui1b.fsf@news.dtpq.com>
Christophe Rhodes <·····@cam.ac.uk> writes:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
> > The Lisp character set (for code) is not Unicode.
>
> Isn't the Lisp character set for code the character set supported by
> the implementation? For conforming code, one should only use standard
> characters of course (I hope no-one here has tabs in their source code).
I think the implementation could support richer character
types than the standard constituent character set.
I never noticed that Tab was missing before!
Hi Christopher C. Stacy,
> Christophe Rhodes <·····@cam.ac.uk> writes:
>
>> ······@news.dtpq.com (Christopher C. Stacy) writes:
>>
>> > The Lisp character set (for code) is not Unicode.
>>
>> Isn't the Lisp character set for code the character set supported by
>> the implementation? For conforming code, one should only use standard
>> characters of course (I hope no-one here has tabs in their source code).
>
> I think the implementation could support richer character
> types than the standard constituent character set.
>
> I never noticed that Tab was missing before!
??? It's not. See CLHS 2.1.4. It's defined as whitespace. Tabs in source
code have the same semantics as a space.
Regards,
Adam
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <uis9xvjqf.fsf@news.dtpq.com>
Adam Warner <······@consulting.net.nz> writes:
> Hi Christopher C. Stacy,
>
> > Christophe Rhodes <·····@cam.ac.uk> writes:
> >
> >> ······@news.dtpq.com (Christopher C. Stacy) writes:
> >>
> >> > The Lisp character set (for code) is not Unicode.
> >>
> >> Isn't the Lisp character set for code the character set supported by
> >> the implementation? For conforming code, one should only use standard
> >> characters of course (I hope no-one here has tabs in their source code).
> >
> > I think the implementation could support richer character
> > types than the standard constituent character set.
> >
> > I never noticed that Tab was missing before!
>
> ??? It's not. See CLHS 2.1.4. It's defined as whitespace.
> Tabs in source code have the same semantics as a space.
At first glance, Figure 2-7 would seem to be inconsistent with
chapter 2.1.3, which says the only non-graphic character is Newline,
and the only non-glyph graphic character is Space. But 2.1.3 is only
talking about the standard characters, which are the ones that can be
used to constitute identifiers. 2.1.4.7 clarifies that certain other
whitespace characters (which are not members of the STANDARD-CHAR repertoire),
such as Tab, can be used to seperate source code tokens.
······@news.dtpq.com (Christopher C. Stacy) writes:
> [...]
> At first glance, Figure 2-7 would seem to be inconsistent with
> chapter 2.1.3, which says the only non-graphic character is Newline,
> and the only non-glyph graphic character is Space. But 2.1.3 is only
> talking about the standard characters, which are the ones that can be
> used to constitute identifiers.
Or rather something along the lines of, "the ones that are necessary
and sufficient to write any portable Common Lisp program"? (I.e.,
not just identifiers.)
> 2.1.4.7 clarifies that certain other
> whitespace characters (which are not members of the STANDARD-CHAR repertoire),
> such as Tab, can be used to seperate source code tokens.
Isn't Tab a semi-standard character?
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <uis9xw0sb.fsf@news.dtpq.com>
Vassil Nikolov <········@poboxes.com> writes:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
> > But 2.1.3 is only talking about the standard characters, which are
> > the ones that can be used to constitute identifiers.
>
> Or rather something along the lines of, "the ones that are necessary
> and sufficient to write any portable Common Lisp program"? (I.e.,
> not just identifiers.)
No. "Standard character" and STANDARD-CHAR are specific terms
defined in the standard.
> > 2.1.4.7 clarifies that certain other whitespace characters (which
> > are not members of the STANDARD-CHAR repertoire), such as Tab, can
> > be used to seperate source code tokens.
>
> Isn't Tab a semi-standard character?
The standard does not have "semi-standard character" in it.
"Christopher C. Stacy" wrote:
> > Isn't Tab a semi-standard character?
>
> The standard does not have "semi-standard character" in it.
It has semi-standard character names. See section 13.1.7.
Paul
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <u655wlsed.fsf@news.dtpq.com>
Paul Dietz <············@motorola.com> writes:
> "Christopher C. Stacy" wrote:
>
> > > Isn't Tab a semi-standard character?
> >
> > The standard does not have "semi-standard character" in it.
>
> It has semi-standard character names. See section 13.1.7.
I stand corrected ,but does this conflict with my point
that only the STANDARD-CHAR can be used for constituents?
"Christopher C. Stacy" wrote:
> I stand corrected ,but does this conflict with my point
> that only the STANDARD-CHAR can be used for constituents?
According to 2.1.4, both Backspace and Rubout (should they
be present) are constituent in standard syntax.
Paul
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <u1xgkld1l.fsf@news.dtpq.com>
Paul Dietz <············@motorola.com> writes:
> "Christopher C. Stacy" wrote:
>
> > I stand corrected ,but does this conflict with my point
> > that only the STANDARD-CHAR can be used for constituents?
>
> According to 2.1.4, both Backspace and Rubout (should they
> be present) are constituent in standard syntax.
Only the characters in 2.1.3 are portable.
From: Christophe Rhodes
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <sqr7ok9rrs.fsf@cam.ac.uk>
······@news.dtpq.com (Christopher C. Stacy) writes:
> Paul Dietz <············@motorola.com> writes:
>
>> "Christopher C. Stacy" wrote:
>>
>> > I stand corrected ,but does this conflict with my point
>> > that only the STANDARD-CHAR can be used for constituents?
>>
>> According to 2.1.4, both Backspace and Rubout (should they
>> be present) are constituent in standard syntax.
>
> Only the characters in 2.1.3 are portable.
If you want to be completely portable, then obviously only
STANDARD-CHAR can be used either for constituents or for any other
purpose, because they're the only ones you're guaranteed to have
around.
If you are working with an implementation which supports characters
other than STANDARD-CHAR, then more than just STANDARD-CHAR can be
used for constituents.
Christophe
From: Christopher C. Stacy
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <u3c0zy7o6.fsf@news.dtpq.com>
Christophe Rhodes <·····@cam.ac.uk> writes:
> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
> > Paul Dietz <············@motorola.com> writes:
> >
> >> "Christopher C. Stacy" wrote:
> >>
> >> > I stand corrected ,but does this conflict with my point
> >> > that only the STANDARD-CHAR can be used for constituents?
> >>
> >> According to 2.1.4, both Backspace and Rubout (should they
> >> be present) are constituent in standard syntax.
> >
> > Only the characters in 2.1.3 are portable.
>
> If you want to be completely portable, then obviously only
> STANDARD-CHAR can be used either for constituents or for any other
> purpose, because they're the only ones you're guaranteed to have
> around.
>
> If you are working with an implementation which supports characters
> other than STANDARD-CHAR, then more than just STANDARD-CHAR can be
> used for constituents.
Yes. (And I've never seen a CL that didn't have more characters.)
From: Paul Dietz
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <415C17C4.E4B7963@motorola.com>
"Christopher C. Stacy" wrote:
>
> Paul Dietz <············@motorola.com> writes:
>
> > "Christopher C. Stacy" wrote:
> >
> > > I stand corrected ,but does this conflict with my point
> > > that only the STANDARD-CHAR can be used for constituents?
> >
> > According to 2.1.4, both Backspace and Rubout (should they
> > be present) are constituent in standard syntax.
>
> Only the characters in 2.1.3 are portable.
In that case, only standard-chars can be used *at all*,
so why are you wasting time talking about constituents?
Paul
······@news.dtpq.com (Christopher C. Stacy) writes:
> Paul Dietz <············@motorola.com> writes:
>
>> "Christopher C. Stacy" wrote:
>>
>> > > Isn't Tab a semi-standard character?
>> >
>> > The standard does not have "semi-standard character" in it.
>>
>> It has semi-standard character names. See section 13.1.7.
>
> I stand corrected ,but does this conflict with my point
> that only the STANDARD-CHAR can be used for constituents?
I may have misunderstood you; I wanted to emphasize (when I wrote
"the ones that are necessary and sufficient to write any portable
Common Lisp program") that the standard characters are used for all
of the syntax, not just for the constituent characters. (And, of
course, the standard characters are sufficient to write all portable
programs.)
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
······@news.dtpq.com (Christopher C. Stacy) writes:
> Paul Dietz <············@motorola.com> writes:
>
> > "Christopher C. Stacy" wrote:
> >
> > > > Isn't Tab a semi-standard character?
> > >
> > > The standard does not have "semi-standard character" in it.
> >
> > It has semi-standard character names. See section 13.1.7.
>
> I stand corrected ,but does this conflict with my point
> that only the STANDARD-CHAR can be used for constituents?
No. Only the STANDARD-CHAR should be used for constituent for the
program to be portable. But an implementation, or a program modifying
the read-table can use any extended character as consitituent.
For example, in clisp:
[64]> (defun �tat (x)
(cdr (assoc x '((:e . �t�) (:p . printemps)
(:h . hivers) (:a automne)))))
�TAT
[65]> (�tat :e)
�T�
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
Pascal Bourguignon <····@mouse-potato.com> writes:
> [...]
> [64]> (defun �tat (x)
> (cdr (assoc x '((:e . �t�) (:p . printemps)
> (:h . hivers) (:a automne)))))
> �TAT
That must be Vivaldi Common Lisp... (Well, he was Italian...)
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.
Hi Christopher C. Stacy,
>> (b) using invert mode, which is necessary to preserve case
>> sensitivity, imposes a psychic cost in addition to the
>> programming overhead of explicit string inverts.
>
> Good reason not to use the :INVERT hack, I suppose,
> but I can't quite tell what you're complaining about.
> This part of the Lisp system (the READ function) has
> already been written for you.
Look at the code I supplied. INVERT&INTERN is a special version of intern
that avoids the not-insignificant overhead of inverting strings before
they are interned each time. When does case sensitivity have to be
preserved and this overhead avoided? In the now common case of converting
XML tags to Lisp symbols. Without caching the generated symbols the
conversion is not efficient.
INTERN cannot be relied upon to achieve this efficiency because caching
every input passed to INTERN would effectively be a memory leak.
The pity is that the symbols in COMMON-LISP are interned in upper case. If
it wasn't for this moving from a case-insensitive to case-sensitive reader
mode would be painless.
Regards,
Adam
The code I am trying to write is this:
Let's say I got a console program that takes input from the keyboard
in form of a pair of symbol and digit and translates it to the
c-function call.
Here I declare the assoc list that binds the pairs with the
list-function symbol:
(setq *assoc-func* (list (list (list 'G 1) 'GetInput)
(list (list 'S 1) 'SetInput)))
Next I need some alien defines for the c-function that will be
GetInputC and SetInputC:
(defmacro def-alien-funcs ()
`(progn
,@(mapcar (lambda (assoc)
`(def-alien-routine
,(format nil "~aC" (cadr assoc))
void (fd integer) (param (* t))))
*assoc-func*)))
To get the list-function based on the input I need:
(defun get-assoc-func (assoclist inplist)
(if (not (null assoclist))
(progn
(if (equal (caar assoclist) inplist)
(cadar assoclist)
(get-assoc-func (cdr assoclist) inplist)))))
And finally when the input occures I call:
(funcall (get-assoc-func *assoc-func* *param-list*) fd)
Which would call the lisp-functions (note that I commented out the
alien-funcall that works without prior def-alien-routine):
(defun GetInput (fd)
(with-alien ((RetVal integer))
;(alien-funcall (extern-alien "GetInputC" (function void integer
(* t))) fd (addr RetVal))
(GetInputC fd (addr RetVal))
(format t "Current input is ~a~%" RetVal)))
(defun SetInput (fd)
(with-alien ((InpVal integer))
(setq InpVal (progn (format t "Enter Value~%") (read)))
;(alien-funcall (extern-alien "SetInputC" (function void integer
(* t))) fd (addr InpVal))))
(SetInputC fd (addr InpVal))))
Another solution could be is to declare c-function all in upper case.
Thus I'd go along with the lisp tradition to convert every symbol in
upper case.
Anyway alien-funcall works without def-alien-routine and it works for
me for now. Somehow when I call (setf (readtable-case *readtable*)
':invert) I got problem with get-assoc-func that evaluates to nul (the
interpreter compains that "the function nil in undefined". (setf
(readtable-case *readtable*) ':preserve) is not a solution either as
the interpreter can't find the lisp function like setq etc. 'cause
probably internally they defined in upper-case and I try to call the
lower case counterparts.
As I see now the upper case conversion has to do with the legacy code
so I respect it :)
Andrew
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<·························@twister.nyc.rr.com>...
> Andrei wrote:
> > Thank you, Kenny
> >
> > I started to read "On Lisp" by Paul Graham and home to get a hang of
> > macros soon.
> > What still bothers me is when I create a list like
> > (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> > (list (list 'S 1) 'SetInput)))
> > With:
> > (defmacro def-alien-funcs ()
> > `(progn
> > ,@(mapcar (lambda (assoc)
> > `(def-alien-routine
> > ,(format nil "~aC" (cadr assoc))
> > void (fd integer) (param (* t))))
> > *assoc-func*)))
> >
> > I get an expanded program:
> > (PROGN
> > (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
> > (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
> >
> > Which is not exactrly what I need because of "GETINPUTC".
> >
> > With (setq *assoc-func2* (list (list (list 'G 1) "GetInput")
> > (list (list 'S 1) "SetInput")))
> >
> > I get the correct result but I need 'GetInput (not a string) in order
> > to use it when I look for a lisp wrapper around GetInputC.
>
> If you explain this with a code snippet which shows what you would like
> to work but does not, we can probably get it working for you. Might be
> as simple as a little more macrology. :)
>
> You might find a solution yourself if you play around with symbol-name
> and (concatenate 'string ...) and case-insensitive string comparators,
> etc etc. But just psot the problem if it seems too hairy.
>
> >
> > I tried to use |GetInput| and also played with (setf (readtable-case
> > *readtable*) ':invert) but it seem to coplicate things.
> > I wonder what's the background of the idea to read all the symbols in
> > "cap" case? Wouldn't it be more natural to leave them as they are?
>
> Good question. Ping the historians. I have only been on board for ten
> years, still a newby myself.
>
> Maybe "Back In the Day" they were not worried about talking to other
> languages, including case-sensitive languages. And I must say as a weak
> typist who has written tons of C that case-insensitivty is a lot more
> relaxing.
>
> Note also that AllegroCL has a modern mode which (I think!) is case
> sensitive, precisely because (I guess!) Lispniks now realize the Outside
> World must be dealt with if Lisp is to grow.
>
> kenny
Andrei wrote:
> The code I am trying to write is this:
> Let's say I got a console program that takes input from the keyboard
> in form of a pair of symbol and digit and translates it to the
> c-function call.
>
> Here I declare the assoc list that binds the pairs with the
> list-function symbol:
>
> (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> (list (list 'S 1) 'SetInput)))
>
>
> Next I need some alien defines for the c-function that will be
> GetInputC and SetInputC:
>
> (defmacro def-alien-funcs ()
> `(progn
> ,@(mapcar (lambda (assoc)
> `(def-alien-routine
> ,(format nil "~aC" (cadr assoc))
> void (fd integer) (param (* t))))
> *assoc-func*)))
>
>
> To get the list-function based on the input I need:
>
> (defun get-assoc-func (assoclist inplist)
> (if (not (null assoclist))
> (progn
> (if (equal (caar assoclist) inplist)
> (cadar assoclist)
> (get-assoc-func (cdr assoclist) inplist)))))
>
>
> And finally when the input occures I call:
> (funcall (get-assoc-func *assoc-func* *param-list*) fd)
>
> Which would call the lisp-functions (note that I commented out the
> alien-funcall that works without prior def-alien-routine):
>
> (defun GetInput (fd)
> (with-alien ((RetVal integer))
> ;(alien-funcall (extern-alien "GetInputC" (function void integer
> (* t))) fd (addr RetVal))
> (GetInputC fd (addr RetVal))
> (format t "Current input is ~a~%" RetVal)))
>
> (defun SetInput (fd)
> (with-alien ((InpVal integer))
> (setq InpVal (progn (format t "Enter Value~%") (read)))
> ;(alien-funcall (extern-alien "SetInputC" (function void integer
> (* t))) fd (addr InpVal))))
> (SetInputC fd (addr InpVal))))
>
>
> Another solution could be is to declare c-function all in upper case.
> Thus I'd go along with the lisp tradition to convert every symbol in
> upper case.
> Anyway alien-funcall works without def-alien-routine and it works for
> me for now. Somehow when I call (setf (readtable-case *readtable*)
> ':invert) I got problem with get-assoc-func that evaluates to nul (the
> interpreter compains that "the function nil in undefined". (setf
> (readtable-case *readtable*) ':preserve) is not a solution either as
> the interpreter can't find the lisp function like setq etc. 'cause
> probably internally they defined in upper-case and I try to call the
> lower case counterparts.
> As I see now the upper case conversion has to do with the legacy code
> so I respect it :)
Sorry, it was a rough night last night. It sounds as if you have things
working satisfactorily, but with a compromise? Otherwise i cannot quite
make out what is not working for you. This all works for me:
(defparameter *assoc-func*
(list (list (list 'G 1) 'GetInput)
(list (list 'S 1) 'SetInput)))
(defun get-assoc-func (assoclist inplist)
(if (not (null assoclist))
(progn
(if (equal (caar assoclist) inplist)
(cadar assoclist)
(get-assoc-func (cdr assoclist) inplist)))))
(defun getinput (fd) (print `(getting ,fd)))
(funcall (get-assoc-func *assoc-func* '(g 1)) 3)
=> (GETTING 3)
Or is the problem when you convert to "GetInput"?
Or is it simply that you were concerned by the unexpected conversion to
uppercase and now realize that (a) it does not break anything and (b)
there is some history behind it, so you are happy now?
Sorry if I missed something.
As a small digression, if you think you will be creating a whole slew of
these command-function pairs with wrappers for alien function calls, you
can probably get even more mileage out of macros.
In my Cello project, I generate OpenGL FFI bindings by globally editing
the C headers so an entry for a function:
WINGDIAPI void APIENTRY glCallLists (GLsizei n, GLenum type, const
GLvoid *lists);
... becomes this rather un-Lispy (but the best I can do with simple
global editing) definition:
(defun-ogl :void "open-gl" "glCallLists" (glsizei n glenum type glvoid
*lists))
My defun-ogl macro expands that to a more general FFI generating macro:
(DEFUN-FFX :VOID "open-gl" "glCallLists" (GLSIZEI N GLENUM TYPE GLVOID
*LISTS)
(PROGN (GLEC '|glCallLists|)))
Which expands to the UFFI def-function macro and a wrapper:
(PROGN
(UFFI:DEF-FUNCTION ("glCallLists" GLCALLLISTS)
((N GLSIZEI) (TYPE GLENUM) (*LISTS (* GLVOID))) :RETURNING :VOID
:MODULE "open-gl")
(DEFUN GL-CALL-LISTS (N TYPE *LISTS)
(LET ((#:N (COERCE N 'INTEGER))
(#:TYPE (COERCE TYPE 'INTEGER)) (#:*LISTS *LISTS))
(PROG1
(GLCALLLISTS #:N #:TYPE #:*LISTS)
(PROGN (GLEC '|glCallLists|)))))
(EVAL-WHEN (COMPILE EVAL LOAD)
(EXPORT '(GLCALLLISTS GL-CALL-LISTS))))
And somewhere I do have a macro which expands multiple definitions, in
the same spirit as your macro which defined multiple alien funcs.
The nice thing about this is that, if I decide to add some more
error-checking before or after every OpenGL call, I just modify these
macros and recompile everything generating all new wrappers.
kenny
> Or is the problem when you convert to "GetInput"?
> Or is it simply that you were concerned by the unexpected conversion to
> uppercase and now realize that (a) it does not break anything and (b)
> there is some history behind it, so you are happy now?
Exactly a) and b)! Actually I use "GetInput" in the list and I
"intern" it later (thanks to Alan Crowe!) when I need to call a lisp
function GetInput (sorry it's still in c-style :).
And I use your macro to define alien functions:
(defmacro def-alien-funcs ()
`(progn
,@(mapcar (lambda (assoc)
`(def-alien-routine
,(format nil "~aC" (cadr assoc))
void (fd integer) (param (* t))))
*assoc-func*)))
So basically my call to lisp function is:
(funcall (intern (string-upcase (get-assoc-func *assoc-func*
*param-list*))) fd)
As for you suggestion about the header files I actually started from
that question to the NG (subj: "Importing system header files in
lisp"), when I asked if there is a nice way like they have it in lush:
(cpheader "#include <linux/videodev.h>)
I am writing a capture driver for linux so I needed some test app to
test the Video for Linux functionality of my driver.
Could be easy to just code it all in c, but I decided to have
something a) more challanging b)That could be interpreded/compiled c)
that I could wrap in GUI later on. Having taken a look on
Perl/Python/Ruby and Lisp I decided to try lisp because I liked it's
consept most of all. After all it's a "father" language of them all!
So, yes, eventually when I become more familiar with macros I'll be up
to something like you did with the OpenGL bindings.
Thank you so much!
Andrew
Hi
You have stumbled upon THE GREAT MISTAKE (IMHO, while wearing flame
proof underwear) of the ANSI Common Lisp Specification.
You'll have to live with it. Yet, before I go on, allow me to point out
that the GNU Coding standard for C and C++ advises you to use
identifiers like
get_input
instead of
GetInput
i.e. Common Lisp is not the only place where StudlyCaps are not so welcome.
So, the first bit of advice is: give up and start using Common Lisp
kosher, halal or properly vegetarian names like
get-input set-input etc etc
You can reserve the StudlyCaps names for strings and connections to
foreign libraries.
I.e. ... when in Rome don't do it like the idiots from Northern Italy :)
As you have already noticed, there are subtle interplays between the
READTABLE-CASE (you can set it to :INVERT) and the value of the
*PRINT-CASE* variable (you can set it to :DOWNCASE.) And it still is
quite complicated and not foolproof.
The reason always given for this, was backward compatibility with
earlier dialects of Lisp and to account for (now mostly disappeared)
uppercase only terminals. OTOH I wasn't there in the standardization
days, and I am still happy that all the rivers of blood that seem to
have been spilt actually have give us the ANSI standard :)
Cheers
--
Marco
Andrei wrote:
> Thank you, Kenny
>
> I started to read "On Lisp" by Paul Graham and home to get a hang of
> macros soon.
> What still bothers me is when I create a list like
> (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> (list (list 'S 1) 'SetInput)))
> With:
> (defmacro def-alien-funcs ()
> `(progn
> ,@(mapcar (lambda (assoc)
> `(def-alien-routine
> ,(format nil "~aC" (cadr assoc))
> void (fd integer) (param (* t))))
> *assoc-func*)))
>
> I get an expanded program:
> (PROGN
> (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
> (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
>
> Which is not exactrly what I need because of "GETINPUTC".
>
> With (setq *assoc-func2* (list (list (list 'G 1) "GetInput")
> (list (list 'S 1) "SetInput")))
>
> I get the correct result but I need 'GetInput (not a string) in order
> to use it when I look for a lisp wrapper around GetInputC.
>
> I tried to use |GetInput| and also played with (setf (readtable-case
> *readtable*) ':invert) but it seem to coplicate things.
> I wonder what's the background of the idea to read all the symbols in
> "cap" case? Wouldn't it be more natural to leave them as they are?
>
> Thanks,
> Andrew
>
>
> Kenny Tilton <·······@nyc.rr.com> wrote in message news:<·····················@twister.nyc.rr.com>...
>
>>Andrei wrote:
>>
>>
>>>Both of you examples work and somehow I prefer the first one. It's
>>>easier for me to understand and it reuses the already defined
>>>*assoc-funcs* list.
>>
>>OK, but then you have not added a reusable tool to your toolkit, because
>>the macro is hard-coded to work against one list. Well, you could rebind
>>the special *assoc-funcs* in the source and then reuse the macro, but
>>then things are starting to get a little perverse.
>>
>>The sneaky way would be to have your macro take advantage of:
>>
>>(defparameter *bb* 42)
>>(symbol-value '*bb*) => 42
>>
>>but that too makes me queasy.
>>
>>
>>
>>>Though I still don't understand all the
>>>intricacies of your examples it'll give me something to digest during
>>>next week.
>>
>>The scary thing is that, since a macro is really just another Lisp
>>function, you can put print statements in the macro body to figure out
>>what is going on. Here is how one could have diagnosed my goofy original
>>offering (simplified):
>>
>>(defmacro reversef (parm-vals)
>> (print (list 'inputs parm-vals (type-of parm-vals)
>> (symbol-value parm-vals)))
>> `(progn
>> ,@(mapcar (lambda (parm-val)
>> (print `(parm-val ',parm-val))
>> `(defparameter ,(car parm-val),(cadr parm-val)))
>> (symbol-value parm-vals))))
>>
>>(defparameter *bindings* '((a 1)(b 2)))
>>
>>(macroexpand-1 '(reversef *bindings*))
>>=>
>>(INPUTS *BINDINGS* SYMBOL ((A 1) (B 2)))
>>(PARM-VAL '(A 1))
>>(PARM-VAL '(B 2))
>>(PROGN (DEFPARAMETER A 1) (DEFPARAMETER B 2))
>>
>>The last line is simply the listener printing the value returned by the
>>macroexpansion. (It works because I used the sneaky trick I hinted at
>>earlier.)
>>
>>But the first three lines after the macroexpansion form are my own
>>debugging statements, and reveal my gaffe: macros see code in symbolic
>>form, so in the orginal *assoc-list* came through not as the list of
>>desired alien funcs but simply as the symbol '*assoc-list*.
>>
>>Macros are a big step up from vanilla Lisp, so (a) I would not be
>>concerned if they seem a little hairy and (b) remember that you can
>>debug them with print statements just like any other code. indeed, the
>>light bulb really went on for me when I saw the output of such
>>debugging, because at first I was really floored by some of the output.
>>
>>kt
Thanks for the lesson, Marco. I didn't mean no flame, really :)
I just rushed from C/C++ to lisp and got a little confused with the
symbols. Now I think with a great help from the NG I am starting to
get it.
Andrew
Marco Antoniotti <·······@cs.nyu.edu> wrote in message news:<··················@typhoon.nyu.edu>...
> Hi
>
> You have stumbled upon THE GREAT MISTAKE (IMHO, while wearing flame
> proof underwear) of the ANSI Common Lisp Specification.
>
> You'll have to live with it. Yet, before I go on, allow me to point out
> that the GNU Coding standard for C and C++ advises you to use
> identifiers like
>
> get_input
>
> instead of
>
> GetInput
>
> i.e. Common Lisp is not the only place where StudlyCaps are not so welcome.
>
> So, the first bit of advice is: give up and start using Common Lisp
> kosher, halal or properly vegetarian names like
>
> get-input set-input etc etc
>
> You can reserve the StudlyCaps names for strings and connections to
> foreign libraries.
>
> I.e. ... when in Rome don't do it like the idiots from Northern Italy :)
>
> As you have already noticed, there are subtle interplays between the
> READTABLE-CASE (you can set it to :INVERT) and the value of the
> *PRINT-CASE* variable (you can set it to :DOWNCASE.) And it still is
> quite complicated and not foolproof.
>
> The reason always given for this, was backward compatibility with
> earlier dialects of Lisp and to account for (now mostly disappeared)
> uppercase only terminals. OTOH I wasn't there in the standardization
> days, and I am still happy that all the rivers of blood that seem to
> have been spilt actually have give us the ANSI standard :)
>
> Cheers
>
> --
> Marco
>
>
>
> Andrei wrote:
> > Thank you, Kenny
> >
> > I started to read "On Lisp" by Paul Graham and home to get a hang of
> > macros soon.
> > What still bothers me is when I create a list like
> > (setq *assoc-func* (list (list (list 'G 1) 'GetInput)
> > (list (list 'S 1) 'SetInput)))
> > With:
> > (defmacro def-alien-funcs ()
> > `(progn
> > ,@(mapcar (lambda (assoc)
> > `(def-alien-routine
> > ,(format nil "~aC" (cadr assoc))
> > void (fd integer) (param (* t))))
> > *assoc-func*)))
> >
> > I get an expanded program:
> > (PROGN
> > (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
> > (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
> >
> > Which is not exactrly what I need because of "GETINPUTC".
> >
> > With (setq *assoc-func2* (list (list (list 'G 1) "GetInput")
> > (list (list 'S 1) "SetInput")))
> >
> > I get the correct result but I need 'GetInput (not a string) in order
> > to use it when I look for a lisp wrapper around GetInputC.
> >
> > I tried to use |GetInput| and also played with (setf (readtable-case
> > *readtable*) ':invert) but it seem to coplicate things.
> > I wonder what's the background of the idea to read all the symbols in
> > "cap" case? Wouldn't it be more natural to leave them as they are?
> >
> > Thanks,
> > Andrew
> >
> >
> > Kenny Tilton <·······@nyc.rr.com> wrote in message news:<·····················@twister.nyc.rr.com>...
> >
> >>Andrei wrote:
> >>
> >>
> >>>Both of you examples work and somehow I prefer the first one. It's
> >>>easier for me to understand and it reuses the already defined
> >>>*assoc-funcs* list.
> >>
> >>OK, but then you have not added a reusable tool to your toolkit, because
> >>the macro is hard-coded to work against one list. Well, you could rebind
> >>the special *assoc-funcs* in the source and then reuse the macro, but
> >>then things are starting to get a little perverse.
> >>
> >>The sneaky way would be to have your macro take advantage of:
> >>
> >>(defparameter *bb* 42)
> >>(symbol-value '*bb*) => 42
> >>
> >>but that too makes me queasy.
> >>
> >>
> >>
> >>>Though I still don't understand all the
> >>>intricacies of your examples it'll give me something to digest during
> >>>next week.
> >>
> >>The scary thing is that, since a macro is really just another Lisp
> >>function, you can put print statements in the macro body to figure out
> >>what is going on. Here is how one could have diagnosed my goofy original
> >>offering (simplified):
> >>
> >>(defmacro reversef (parm-vals)
> >> (print (list 'inputs parm-vals (type-of parm-vals)
> >> (symbol-value parm-vals)))
> >> `(progn
> >> ,@(mapcar (lambda (parm-val)
> >> (print `(parm-val ',parm-val))
> >> `(defparameter ,(car parm-val),(cadr parm-val)))
> >> (symbol-value parm-vals))))
> >>
> >>(defparameter *bindings* '((a 1)(b 2)))
> >>
> >>(macroexpand-1 '(reversef *bindings*))
> >>=>
> >>(INPUTS *BINDINGS* SYMBOL ((A 1) (B 2)))
> >>(PARM-VAL '(A 1))
> >>(PARM-VAL '(B 2))
> >>(PROGN (DEFPARAMETER A 1) (DEFPARAMETER B 2))
> >>
> >>The last line is simply the listener printing the value returned by the
> >>macroexpansion. (It works because I used the sneaky trick I hinted at
> >>earlier.)
> >>
> >>But the first three lines after the macroexpansion form are my own
> >>debugging statements, and reveal my gaffe: macros see code in symbolic
> >>form, so in the orginal *assoc-list* came through not as the list of
> >>desired alien funcs but simply as the symbol '*assoc-list*.
> >>
> >>Macros are a big step up from vanilla Lisp, so (a) I would not be
> >>concerned if they seem a little hairy and (b) remember that you can
> >>debug them with print statements just like any other code. indeed, the
> >>light bulb really went on for me when I saw the output of such
> >>debugging, because at first I was really floored by some of the output.
> >>
> >>kt
From: ·········@cern.ch
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <yzowtyeooof.fsf@cern.ch>
Andrei> I get an expanded program:
Andrei> (PROGN
Andrei> (DEF-ALIEN-ROUTINE "GETINPUTC" VOID (FD INTEGER) (PARAM (* T)))
Andrei> (DEF-ALIEN-ROUTINE "SETINPUTC" VOID (FD INTEGER) (PARAM (* T)))), T
Andrei> Which is not exactrly what I need because of "GETINPUTC".
As you seem to be using CMUCL or a derivative, you might consider
passing a list as the first argument to DEF-ALIEN-ROUTINE.
(def-alien-routine ("GetInput" get-input)
void
(fd integer) (param (* t)))
Ole
Andrei wrote:
I get the correct result but I need 'GetInput (not a
string) in order to use it when I look for a lisp
wrapper around GetInputC.
I tried to use |GetInput| and also played with (setf
(readtable-case *readtable*) ':invert) but it seem to
coplicate things.
Does
(intern (string-upcase "GetInput")) => GETINPUT
help?
Alan Crowe
Edinburgh
Scotland
Yep. It does the trick! Thanks Alan.
I remember I played with intern before I just didn't put string-upcase
in between so it didn't work for me than and I dropped the idea.
Thanks a lot.
Andrew
Alan Crowe <····@cawtech.freeserve.co.uk> wrote in message news:<··············@cawtech.freeserve.co.uk>...
> Andrei wrote:
>
> I get the correct result but I need 'GetInput (not a
> string) in order to use it when I look for a lisp
> wrapper around GetInputC.
>
> I tried to use |GetInput| and also played with (setf
> (readtable-case *readtable*) ':invert) but it seem to
> coplicate things.
>
> Does
>
> (intern (string-upcase "GetInput")) => GETINPUT
>
> help?
>
> Alan Crowe
> Edinburgh
> Scotland
·········@yahoo.com (Andrei) writes:
> I tried to use |GetInput| and also played with (setf (readtable-case
> *readtable*) ':invert) but it seem to coplicate things.
> I wonder what's the background of the idea to read all the symbols in
> "cap" case? Wouldn't it be more natural to leave them as they are?
I recommend giving :invert another chance; I routinely work with an
:invert readtable-case (which SLIME supports nicely). Sure, it's a
compromise between what we have (all of Common Lisp being in/on
uppercase symbols) and what would be nice to have (a "modern" lisp,
case-wise). But the reason we still use upper-case Lisps is because
it's just not worth all that effort to change such a trivial thing.
Especially when there's :invert.
The trick to using :invert to talk to outside languages, is to
"uninvert" your symbol names before you use them. This lets you write
them the same as you would in the other language, without having to
shout in your Lisp code. Eg, as a part of the Objective-C integration
I'm (slowly) working on for SBCL, we have the following functions:
(defun invert-string (string)
(labels ((every-alpha (fn string)
(every (lambda (char)
(or (and (alpha-char-p char) (funcall fn char))
(not (alpha-char-p char))))
string)))
(cond
((every-alpha #'upper-case-p string) (string-downcase string))
((every-alpha #'lower-case-p string) (string-upcase string))
(t string))))
(defun objc-string (spec)
"Like CL:STRING, but uninverts inverted-case symbols."
(etypecase spec
(string spec)
(symbol (invert-string (symbol-name spec)))))
Now I can take the car of a list like I normally would: (car list).
*And* I can write calls to ObjC methods comfortably:
(getFoo obj)
(setFoo obj new-foo)
(frobThing obj thing :nTimes n)
From: Peter Seibel
Subject: Re: How to prevent cdr from capitalizing symbols?
Date:
Message-ID: <m3hdpgcto6.fsf@javamonkey.com>
···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> ·········@yahoo.com (Andrei) writes:
>
>> I tried to use |GetInput| and also played with (setf (readtable-case
>> *readtable*) ':invert) but it seem to coplicate things.
>> I wonder what's the background of the idea to read all the symbols in
>> "cap" case? Wouldn't it be more natural to leave them as they are?
>
> I recommend giving :invert another chance; I routinely work with an
> :invert readtable-case (which SLIME supports nicely). Sure, it's a
> compromise between what we have (all of Common Lisp being in/on
> uppercase symbols) and what would be nice to have (a "modern" lisp,
> case-wise). But the reason we still use upper-case Lisps is because
> it's just not worth all that effort to change such a trivial thing.
> Especially when there's :invert.
>
> The trick to using :invert to talk to outside languages, is to
> "uninvert" your symbol names before you use them. This lets you write
> them the same as you would in the other language, without having to
> shout in your Lisp code. Eg, as a part of the Objective-C integration
> I'm (slowly) working on for SBCL, we have the following functions:
>
> (defun invert-string (string)
> (labels ((every-alpha (fn string)
> (every (lambda (char)
> (or (and (alpha-char-p char) (funcall fn char))
> (not (alpha-char-p char))))
> string)))
> (cond
> ((every-alpha #'upper-case-p string) (string-downcase string))
> ((every-alpha #'lower-case-p string) (string-upcase string))
> (t string))))
Pedantically speaking, shouldn't you use both-case-p there? (Unless
I'm more tired than I think, it seems like your boolean logic is more
complex than it needs to be:
(defun invert-string (string)
(labels ((every-case (fn string)
(every #'(lambda (char)
(or (not (both-case-p char)) (funcall fn char)))
string)))
(cond
((every-case #'upper-case-p string) (string-downcase string))
((every-case #'lower-case-p string) (string-upcase string))
(t string))))
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp