I apologize if this question is absurdly simple, and I just haven't
learned the right resource to find it from, but it's something I've
been struggling with all morning.
I'm trying to create a macro that will, as part of it's expansion,
create an object with specific initargs.
i.e. I want to say:
(update-table 'ou "imported_table" ou-name "firstOU")
and have it expand to:
(LET
((LST1 (SELECT 'OU :FLATP T))
(LST2
(QUERY
(CONCATENATE 'STRING "SELECT DISTINCT " "FirstOU" " FROM "
"IMPORTED_TABLE")
:FLATP T)))
(DOLIST (X LST2)
(SETF LST1
(PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
#'(LAMBDA (X) (SLOT-VALUE X 'OU-NAME)) :TEST #'EQUAL)))
(DOLIST (X LST1) (UPDATE-RECORD-FROM-SLOTS X '(OU-NAME)))
(VALUES LST1 (LENGTH LST1)))
The problem I'm running into is the line
(PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
Always ends up as:
(PUSHNEW (MAKE-INSTANCE 'OU :|| OU-NAME X) :KEY
I cannot seem to get the colon prepended to "ou-name" in the macro
expansion. Instead I get an odd :||, which I can't seem to find the
meaning of.. well.. anywhere.
The simple answer seems to be to prepend the colon to the parameter
when I make the call to the macro, but I need the colon to -not- be
there on the next line, where I need:
#'(lambda (x) (slot-value x 'ou-name)) :test #'equal)))
This is the macro as composed thus far:
(defmacro update-table (table-class table-name distinct-slot field-
name)
`(let ((lst1 (select ,table-class :flatp t))
(lst2 (query (concatenate 'string "SELECT DISTINCT " ,field-name "
FROM " ,table-name) :flatp t)))
(dolist (x lst2)
(setf lst1 (pushnew (make-instance ,table-class :,distinct-slot
x)
:key #'(lambda (x) (slot-value x ,distinct-slot))
:test #'equal)))
(dolist (x lst1)
(update-record-from-slots x '(,distinct-slot)))
(values lst1 (length lst1))))
I recognize this may be a rather simple case, but I'm learning that
google doesn't really listen when I ask it "What is :|| ??" even when
I say "sharpsign vertical-bar vertical-bar"
For what it's worth, I'm using clisp 2.46 with clsql 4.0.3
Thanks in advance,
~Alex
On Oct 15, 10:55 am, "a'Lex" <·········@gmail.com> wrote:
> I apologize if this question is absurdly simple, and I just haven't
> learned the right resource to find it from, but it's something I've
> been struggling with all morning.
>
> I'm trying to create a macro that will, as part of it's expansion,
> create an object with specific initargs.
>
> i.e. I want to say:
> (update-table 'ou "imported_table" ou-name "firstOU")
>
> and have it expand to:
>
> (LET
> ((LST1 (SELECT 'OU :FLATP T))
> (LST2
> (QUERY
> (CONCATENATE 'STRING "SELECT DISTINCT " "FirstOU" " FROM "
> "IMPORTED_TABLE")
> :FLATP T)))
> (DOLIST (X LST2)
> (SETF LST1
> (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
> #'(LAMBDA (X) (SLOT-VALUE X 'OU-NAME)) :TEST #'EQUAL)))
> (DOLIST (X LST1) (UPDATE-RECORD-FROM-SLOTS X '(OU-NAME)))
> (VALUES LST1 (LENGTH LST1)))
>
> The problem I'm running into is the line
> (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
>
> Always ends up as:
> (PUSHNEW (MAKE-INSTANCE 'OU :|| OU-NAME X) :KEY
>
> I cannot seem to get the colon prepended to "ou-name" in the macro
> expansion. Instead I get an odd :||, which I can't seem to find the
> meaning of.. well.. anywhere.
> The simple answer seems to be to prepend the colon to the parameter
> when I make the call to the macro, but I need the colon to -not- be
> there on the next line, where I need:
> #'(lambda (x) (slot-value x 'ou-name)) :test #'equal)))
>
> This is the macro as composed thus far:
> (defmacro update-table (table-class table-name distinct-slot field-
> name)
> `(let ((lst1 (select ,table-class :flatp t))
> (lst2 (query (concatenate 'string "SELECT DISTINCT " ,field-name "
> FROM " ,table-name) :flatp t)))
> (dolist (x lst2)
> (setf lst1 (pushnew (make-instance ,table-class :,distinct-slot
> x)
> :key #'(lambda (x) (slot-value x ,distinct-slot))
> :test #'equal)))
> (dolist (x lst1)
> (update-record-from-slots x '(,distinct-slot)))
> (values lst1 (length lst1))))
>
> I recognize this may be a rather simple case, but I'm learning that
> google doesn't really listen when I ask it "What is :|| ??" even when
> I say "sharpsign vertical-bar vertical-bar"
>
> For what it's worth, I'm using clisp 2.46 with clsql 4.0.3
> Thanks in advance,
> ~Alex
Okay, I've somewhat solved my own problem, but the solution seems like
a complete kludge.. so someone please let me know if there's a better
way to do this:
(defmacro update-table (table-class table-name distinct-slot field-
name)
`(let ((lst1 (select ,table-class :flatp t))
(lst2 (query (concatenate 'string "SELECT DISTINCT " ,field-name "
FROM " ,table-name) :flatp t)))
(dolist (x lst2)
(setf lst1 (pushnew (make-instance ,table-class ,(intern
(symbol-name distinct-slot) "KEYWORD") x)
:key #'(lambda (x) (slot-value x ,distinct-slot))
:test #'equal)))
(dolist (x lst1)
(update-record-from-slots x '(,distinct-slot)))
(values lst1 (length lst1))))
The reason it seems a kludge to me is that I'm converting a symbol to
a string, just to convert it back to a symbol again:
(intern (symbol-name distinct-slot) "KEYWORD")
Is there a better way?
"a'Lex" <·········@gmail.com> writes:
> The reason it seems a kludge to me is that I'm converting a symbol to
> a string, just to convert it back to a symbol again:
> (intern (symbol-name distinct-slot) "KEYWORD")
>
> Is there a better way?
Well you could directly "import" your symbol into the KEYWORD package,
but that wouldn't make it a keyword:
C/USER[82]> (defvar *example* '42)
*EXAMPLE*
C/USER[83]> (import '*example* :keyword)
T
C/USER[84]> :*example*
42
C/USER[85]> :*control*
:*CONTROL*
C/USER[86]> (keywordp ':*example*)
NIL
C/USER[87]> (keywordp ':*control*)
T
C/USER[88]>
Interning the symbol-name is indeed the most direct way to make a keyword from a symbol.
--
__Pascal Bourguignon__
On 2008-10-15, a'Lex <·········@gmail.com> wrote:
> The reason it seems a kludge to me is that I'm converting a symbol to
> a string, just to convert it back to a symbol again:
> (intern (symbol-name distinct-slot) "KEYWORD")
Your original problem statement is that you want a macro call of the
form:
(macro ... name ...)
to produce an expansion like this:
(EXPANSION ... :NAME ...)
One of the arguments to the macro is a symbol, and you want to convert this
to a symbol of the same name, but in the keyword package.
So the kludge (treating symbols as strings) is a direct, inescapable
consequence of the functional requirements for your macro.
"a'Lex" <·········@gmail.com> writes:
> The problem I'm running into is the line
> (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
>
> Always ends up as:
> (PUSHNEW (MAKE-INSTANCE 'OU :|| OU-NAME X) :KEY
>
> I cannot seem to get the colon prepended to "ou-name" in the macro
> expansion. Instead I get an odd :||, which I can't seem to find the
> meaning of.. well.. anywhere.
My suspicion is that you have somehow introduced a non-printing
delimiter character into your source file between ":" and "OU-NAME", and
that is what is making the reader create an empty name for the keyword.
I would try just deleting the entire (MAKE-INSTANCE ...) form and typing
it in again.
There isn't any chance that you have some type of typing macro setup
that uses : as a prefix character to insert some type of accented
character, do you? What editor are you using to write the code?
--
Thomas A. Russ, USC/Information Sciences Institute
In article
<····································@l62g2000hse.googlegroups.com>,
"a'Lex" <·········@gmail.com> wrote:
> I apologize if this question is absurdly simple, and I just haven't
> learned the right resource to find it from, but it's something I've
> been struggling with all morning.
>
> I'm trying to create a macro that will, as part of it's expansion,
> create an object with specific initargs.
>
> i.e. I want to say:
> (update-table 'ou "imported_table" ou-name "firstOU")
>
> and have it expand to:
>
> (LET
> ((LST1 (SELECT 'OU :FLATP T))
> (LST2
> (QUERY
> (CONCATENATE 'STRING "SELECT DISTINCT " "FirstOU" " FROM "
> "IMPORTED_TABLE")
> :FLATP T)))
> (DOLIST (X LST2)
> (SETF LST1
> (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
> #'(LAMBDA (X) (SLOT-VALUE X 'OU-NAME)) :TEST #'EQUAL)))
> (DOLIST (X LST1) (UPDATE-RECORD-FROM-SLOTS X '(OU-NAME)))
> (VALUES LST1 (LENGTH LST1)))
>
> The problem I'm running into is the line
> (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
>
> Always ends up as:
> (PUSHNEW (MAKE-INSTANCE 'OU :|| OU-NAME X) :KEY
>
> I cannot seem to get the colon prepended to "ou-name" in the macro
> expansion. Instead I get an odd :||, which I can't seem to find the
> meaning of.. well.. anywhere.
> The simple answer seems to be to prepend the colon to the parameter
> when I make the call to the macro, but I need the colon to -not- be
> there on the next line, where I need:
> #'(lambda (x) (slot-value x 'ou-name)) :test #'equal)))
>
> This is the macro as composed thus far:
> (defmacro update-table (table-class table-name distinct-slot field-
> name)
> `(let ((lst1 (select ,table-class :flatp t))
> (lst2 (query (concatenate 'string "SELECT DISTINCT " ,field-name "
> FROM " ,table-name) :flatp t)))
> (dolist (x lst2)
> (setf lst1 (pushnew (make-instance ,table-class :,distinct-slot
> x)
You can't write :,foo and expect it do something useful
|| is a symbol with a name of length zero.
:|| is a symbol with a name of length zero in the keyword package.)
Vertical bars are for symbols. |FOO| and FOO and foo
are usually read as the same symbol. But you
can use it to have different case or even spaces in symbols:
|this is ALSO a symbol|
CL-USER 66 > (describe '|this is ALSO a symbol|)
|this is ALSO a symbol| is a SYMBOL
NAME "this is ALSO a symbol"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The COMMON-LISP-USER package, 78/256 internal, 0/4 external>
If you don't know what something is, DESCRIBE it:
CL-USER 64 > (describe :||)
:|| is a SYMBOL
NAME ""
VALUE :||
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The KEYWORD package, 0/4 internal, 5369/8192 external>
if you have a symbol FOO and you want a symbol :FOO, then do
CL-USER 65 > (intern (symbol-name 'foo) "KEYWORD")
:FOO
NIL
> :key #'(lambda (x) (slot-value x ,distinct-slot))
> :test #'equal)))
> (dolist (x lst1)
> (update-record-from-slots x '(,distinct-slot)))
> (values lst1 (length lst1))))
>
> I recognize this may be a rather simple case, but I'm learning that
> google doesn't really listen when I ask it "What is :|| ??" even when
> I say "sharpsign vertical-bar vertical-bar"
>
> For what it's worth, I'm using clisp 2.46 with clsql 4.0.3
> Thanks in advance,
> ~Alex
--
http://lispm.dyndns.org/
On Oct 15, 11:50 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@l62g2000hse.googlegroups.com>,
>
>
>
> "a'Lex" <·········@gmail.com> wrote:
> > I apologize if this question is absurdly simple, and I just haven't
> > learned the right resource to find it from, but it's something I've
> > been struggling with all morning.
>
> > I'm trying to create a macro that will, as part of it's expansion,
> > create an object with specific initargs.
>
> > i.e. I want to say:
> > (update-table 'ou "imported_table" ou-name "firstOU")
>
> > and have it expand to:
>
> > (LET
> > ((LST1 (SELECT 'OU :FLATP T))
> > (LST2
> > (QUERY
> > (CONCATENATE 'STRING "SELECT DISTINCT " "FirstOU" " FROM "
> > "IMPORTED_TABLE")
> > :FLATP T)))
> > (DOLIST (X LST2)
> > (SETF LST1
> > (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
> > #'(LAMBDA (X) (SLOT-VALUE X 'OU-NAME)) :TEST #'EQUAL)))
> > (DOLIST (X LST1) (UPDATE-RECORD-FROM-SLOTS X '(OU-NAME)))
> > (VALUES LST1 (LENGTH LST1)))
>
> > The problem I'm running into is the line
> > (PUSHNEW (MAKE-INSTANCE 'OU :OU-NAME X) :KEY
>
> > Always ends up as:
> > (PUSHNEW (MAKE-INSTANCE 'OU :|| OU-NAME X) :KEY
>
> > I cannot seem to get the colon prepended to "ou-name" in the macro
> > expansion. Instead I get an odd :||, which I can't seem to find the
> > meaning of.. well.. anywhere.
> > The simple answer seems to be to prepend the colon to the parameter
> > when I make the call to the macro, but I need the colon to -not- be
> > there on the next line, where I need:
> > #'(lambda (x) (slot-value x 'ou-name)) :test #'equal)))
>
> > This is the macro as composed thus far:
> > (defmacro update-table (table-class table-name distinct-slot field-
> > name)
> > `(let ((lst1 (select ,table-class :flatp t))
> > (lst2 (query (concatenate 'string "SELECT DISTINCT " ,field-name "
> > FROM " ,table-name) :flatp t)))
> > (dolist (x lst2)
> > (setf lst1 (pushnew (make-instance ,table-class :,distinct-slot
> > x)
>
> You can't write :,foo and expect it do something useful
>
> || is a symbol with a name of length zero.
> :|| is a symbol with a name of length zero in the keyword package.)
>
> Vertical bars are for symbols. |FOO| and FOO and foo
> are usually read as the same symbol. But you
> can use it to have different case or even spaces in symbols:
>
> |this is ALSO a symbol|
>
> CL-USER 66 > (describe '|this is ALSO a symbol|)
>
> |this is ALSO a symbol| is a SYMBOL
> NAME "this is ALSO a symbol"
> VALUE #<unbound value>
> FUNCTION #<unbound function>
> PLIST NIL
> PACKAGE #<The COMMON-LISP-USER package, 78/256 internal, 0/4 external>
>
> If you don't know what something is, DESCRIBE it:
>
> CL-USER 64 > (describe :||)
>
> :|| is a SYMBOL
> NAME ""
> VALUE :||
> FUNCTION #<unbound function>
> PLIST NIL
> PACKAGE #<The KEYWORD package, 0/4 internal, 5369/8192 external>
>
> if you have a symbol FOO and you want a symbol :FOO, then do
>
> CL-USER 65 > (intern (symbol-name 'foo) "KEYWORD")
> :FOO
> NIL
>
> > :key #'(lambda (x) (slot-value x ,distinct-slot))
> > :test #'equal)))
> > (dolist (x lst1)
> > (update-record-from-slots x '(,distinct-slot)))
> > (values lst1 (length lst1))))
>
> > I recognize this may be a rather simple case, but I'm learning that
> > google doesn't really listen when I ask it "What is :|| ??" even when
> > I say "sharpsign vertical-bar vertical-bar"
>
> > For what it's worth, I'm using clisp 2.46 with clsql 4.0.3
> > Thanks in advance,
> > ~Alex
>
> --http://lispm.dyndns.org/
Rainer,
Thanks for the help. :) I have the sense that we were on the same
page here, as I apparently figured out how to do exactly what you just
replied with at the nearly exact instant that you started to reply to
me. The coincidence of the timing is nothing short of awesome, heh.
I appreciate the tips, they'll help me as I further this quest of
mine to fully understand lisp.