From: ········@ptcstudios.com
Subject: newbie Lisp question
Date: 
Message-ID: <6dDGOGLUjzLw8Cy92neobKcyZGZV@4ax.com>
I am trying to make a macro which creates functions, but I do not know
how to create a the symbol to be used in the expanded code.

Example:

( defmacro defMyHashThing (name)
   `(defun make-,name () (make-hash-table)))

When I run macroexpand on this I get:

: (macroexpand-1 '(defMyHashThing foo))

(DEFUN MAKE- FOO NIL (MAKE-HASH-TABLE))

Note that a space is inserted between "make-" and "foo".  The macro
will not put the "make-" and the "foo" together, so only a function
called "make-" is defined when the macro is evaluated.

Thanks.

········@ptcstudios.com

From: Barry Margolin
Subject: Re: newbie Lisp question
Date: 
Message-ID: <aAAx4.84$Ag3.1736@burlma1-snr2>
In article <····························@4ax.com>,
 <········@ptcstudios.com> wrote:
>
>I am trying to make a macro which creates functions, but I do not know
>how to create a the symbol to be used in the expanded code.
>
>Example:
>
>( defmacro defMyHashThing (name)
>   `(defun make-,name () (make-hash-table)))
>
>When I run macroexpand on this I get:
>
>: (macroexpand-1 '(defMyHashThing foo))
>
>(DEFUN MAKE- FOO NIL (MAKE-HASH-TABLE))
>
>Note that a space is inserted between "make-" and "foo".  The macro
>will not put the "make-" and the "foo" together, so only a function
>called "make-" is defined when the macro is evaluated.

You have to create a symbol, using MAKE-SYMBOl or INTERN.

(defmacro defMyHashThing (name)
  `(defun ,(intern (concatenate 'string "MAKE-" name)) ()
     (make-hash-table)))

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Pierre R. Mai
Subject: Re: newbie Lisp question
Date: 
Message-ID: <87ya7t13i3.fsf@orion.dent.isdn.cs.tu-berlin.de>
········@ptcstudios.com writes:

> I am trying to make a macro which creates functions, but I do not know
> how to create a the symbol to be used in the expanded code.
> 
> Example:
> 
> ( defmacro defMyHashThing (name)
>    `(defun make-,name () (make-hash-table)))

(defmacro defmyhashthing (name)
  (let* ((fun-name (concatenate 'string "MAKE-" (symbol-name name)))
         (fun-sym (intern fun-name (symbol-package name))))
    `(defun ,fun-sym () (make-hash-table))))

Backquote only works for putting together lists, it doesn't know
anything about symbols or other data-structures.

The code to create the proper symbol is a bit complicated, because you 
need to do two things:

a) Create a symbol named "MAKE-FOO" out of "MAKE-" and "FOO", that is
b) interned in the package that the original name symbol came from.

The second part is important, because you want

(in-package :BAR)

(defmyhashthing baz::foo)

to create baz::make-foo and not bar::make-foo.

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Erik Naggum
Subject: Re: newbie Lisp question
Date: 
Message-ID: <3161562827781681@naggum.no>
* Pierre R. Mai
| Backquote only works for putting together lists, it doesn't know
| anything about symbols or other data-structures.

  backquote works on sequences, which includes vectors and lists.

#:Erik
From: Axel Schairer
Subject: Re: newbie Lisp question
Date: 
Message-ID: <fm9og8ogxc1.fsf@methven.dai.ed.ac.uk>
····@acm.org (Pierre R. Mai) writes:
> The code to create the proper symbol is a bit complicated, because you 
> need to do two things:
> 
> a) Create a symbol named "MAKE-FOO" out of "MAKE-" and "FOO", that is
> b) interned in the package that the original name symbol came from.
> 
> The second part is important, because you want
> 
> (in-package :BAR)
> 
> (defmyhashthing baz::foo)
> 
> to create baz::make-foo and not bar::make-foo.

There is a problem with symbols used from other packages.

	(defmyhashthing list) 

interns MAKE-LIST in CL as an internal symbol (provided you use the CL
package).  So sometimes you might want to have the symbol interned in
the current package.  A more detailed explanation of this by Kent M
Pitman is at
http://x46.deja.com/getdoc.xp?AN=359498244&search=thread&CONTEXT=952603394.1921974274&HIT_CONTEXT=&HIT_NUM=&hitnum=2

Axel
From: Robert Monfera
Subject: Re: newbie Lisp question
Date: 
Message-ID: <38C7C1E0.B0BE1FF1@fisec.com>
Pierre R. Mai wrote:

> (defmacro defmyhashthing (name)
>   (let* ((fun-name (concatenate 'string "MAKE-" (symbol-name name)))
>          (fun-sym (intern fun-name (symbol-package name))))
>     `(defun ,fun-sym () (make-hash-table))))

When is it encouraged to put together symbol names though?  By default,
DEFSTRUCT produces a host of functions with glued names, but it isn't
common in CL.  For example, CLOS just uses MAKE-INSTANCE (OK, it's a GF
anyway) and TYPEP.  A reason is that such glueing benefits humans only
and does not benefit code walkers and other tools, and the benefit is
little if any.

Is it an indication that automagical function (or whatever) creation
with glued names is rarely encouraged?  Any examples when it's the best
way of achieving something other than system integration?

Robert
From: Tim Bradshaw
Subject: Re: newbie Lisp question
Date: 
Message-ID: <ey31z5k92vh.fsf@cley.com>
* Robert Monfera wrote:

> Is it an indication that automagical function (or whatever) creation
> with glued names is rarely encouraged?  Any examples when it's the best
> way of achieving something other than system integration?

Whenever you want a bunch of accessor-type names, or a bunch of
functions with related names it's a good thing.

For instance CLIM has `spread` and `nospread' versions of a whole load
of things, with names like DRAW-LINE (takes arguments which are point
objects) and DRAW-LINE* (takes x, y pairs).  These are generated from
the same macro (which I think may actually generate some other
definitions as well while it's at it).

I guess you might consider that system integration though?

--tim
From: Erik Naggum
Subject: Re: newbie Lisp question
Date: 
Message-ID: <3161565178384561@naggum.no>
* Robert Monfera <·······@fisec.com>
| When is it encouraged to put together symbol names though?  By default,
| DEFSTRUCT produces a host of functions with glued names, but it isn't
| common in CL.
| 
| Is it an indication that automagical function (or whatever) creation with
| glued names is rarely encouraged?  Any examples when it's the best way of
| achieving something other than system integration?

  recently, I wrote that making some concepts hard to express didn't cause
  people to suffer from having to express them, but made the concepts
  suffer because they would be underutilized.  humans, falling prey to the
  siren song of convenience, will always think this way.  therefore, the
  languages we use must make smart concepts convenient to express and dumb
  concepts inconvenient to express.  the natural tendency is the opposite.

(intern (concatenate 'string (symbol-name #:make-) (symbol-name symbol))
        (symbol-package symbol))

  will return a new symbol prefixed with "make-" in the same package as the
  symbol without the prefix (thanks for that careful bit, Pierre), but is
  this hard to read?  is it a lot of "internal stuff" that people shouldn't
  ned to worry about?  I dont' think so.  I think this is the smallest you
  can do, short of writing a function specifically to glue symbol names
  that does all this, but think about its hypothetical interface for a
  second: it would naturally want two symbols, but which one is prefix and
  which one is suffix?  (resist the temptation to search for the hyphen!)
  so either you get two functions or you supply the package separately, or
  perhaps you think you could supply one string and one symbol, but either
  way, you have caused the user of your function to exercise a lot more
  brainpower on your symbol-glue function than on the expression above,
  which should be a no-brainer for an experienced Common Lisp programmer in
  a way the symbol-glue functions wouldn't be because they are infrequently
  used.  and if they aren't infrequently used, we're back to Robert's
  question: should we encourage this?  I don't think we should, either, so
  it would be bad if it were too convenient to do it.

  FORMAT is clearly in the "too convenient" camp, since it makes doing it
  the wrong way so convenient, and burdens the user with case conversion
  issues in the reader and the printer at the same time.

  but consider a More Common Lisp that does no case conversion in the
  reader or the printer (which is more common than doing it, hence my
  punnish name), with what-you-see-is-what-you-get symbol names:

(intern (format nil "make-~a" symbol) (symbol-package symbol))

  consider all the idiomatic stuff we got rid of: either an uninterned or
  keyword symbol just to get the symbol name right or an upper-case prefix
  string literal, and extracting the symbol-name part.  this idiomatic
  burden is a no-brainer to an experienced Common Lisp programmer, but
  _acquiring_ the expertise so it becomes a no-brainer is not effortless at
  all, and probably involves struggling and lots of confusion until the
  full ramifications of Common Lisp's attitude to case are internalized.

  so instead of encouraging the convenient creation of symbols, we have an
  elaborate scheme to discourage people from looking at symbol names and
  only use the symbols as symbols, but this works directly against the work
  needed to acquire the expertise in using them correctly!  since symbols
  is very powerful abstraction mechanism, and case conversion is also a
  very powerful mechanism in human communication (it has definite value,
  but by informed choice, not default), we've forced ourselves out on a
  limb every time we have to deal with them, and some are worrying that any
  proposal to fix this is akin to cutting the limb on the dumb side.  this
  is a case of making a smart concept cumbersome to express, and forces us
  to consider more convenient options merely for the sake of convenience --
  it should have been _sufficiently_ convenient to begin with not to have
  to worry about case conversion details.

  let's find a way to make Common Lisp work with readtable-case :preserve
  and lower-case symbol names, so what-you-see-is-what-you-get-ness is also
  preserved for experienced and novice programmer alike, and we can do
  smart stuff without having to be too clever, too.

#:Erik
From: Tim Bradshaw
Subject: Re: newbie Lisp question
Date: 
Message-ID: <ey3zos764bn.fsf@cley.com>
* Erik Naggum wrote:
>   let's find a way to make Common Lisp work with readtable-case :preserve
>   and lower-case symbol names, so what-you-see-is-what-you-get-ness is also
>   preserved for experienced and novice programmer alike, and we can do
>   smart stuff without having to be too clever, too.

It's certainly the case that making symbols from other symbols is one
of the classic CL `gotcha's -- I've seen code written by Lisp
programmers with much more experience than me which just gets this
wrong (I only found out because I habitually have my CL environments
print in lower-case).

So a CL with more obvious and flexible handling of case would clearly
be a good thing.

But I think that there *are* advantages to case-insensitive readers.
Specifically, case-sensitive languages seem to be vulnerable to the
drEadEd studlycaps vIrUs.  C seems to be badly infected with this
despite having grown up with powerful Unix antibodies, and I think C++
was born with it (Java too I guess).

While I appreciate that CL probably does need to talk with these
infested languages, and thus presumably will in due course become
fully studly itself, I find the prospect sad.

--tim

-- 
tim bradshaw, ClEy limiTeD
From: Erik Naggum
Subject: Re: newbie Lisp question
Date: 
Message-ID: <3161707555093615@naggum.no>
* Tim Bradshaw <···@cley.com>
| But I think that there *are* advantages to case-insensitive readers.
| Specifically, case-sensitive languages seem to be vulnerable to the
| drEadEd studlycaps vIrUs.  C seems to be badly infected with this despite
| having grown up with powerful Unix antibodies, and I think C++ was born
| with it (Java too I guess).

  the studlycaps infection is a serious issue.  however, I think it grew
  out of the stupid way symbols are constructed in some languages, with a
  fixed set of characters available in symbol names and everything else
  being "parsed" as operators and whatnot, causing people to get scared of
  anything that looks like blank spaces.  underscores, in particular, are
  used much like "visible blanks", but they look so ugly it's no wonder
  people don't use them.  if you aren't afraid of what might look like an
  operator, foo-bar-zot beats foo_bar_zot hands down any day, but if you
  are afraid of operator look-alikes, you need fooBarZot to feel "safe".

| While I appreciate that CL probably does need to talk with these infested
| languages, and thus presumably will in due course become fully studly
| itself, I find the prospect sad.

  I don't think this will happen, but I think it's _less_ likely to happen
  with a lower-case Lisp than an upper-case Lisp.  the reason may seem
  counter-intuitive, but here goes: in an upper-case Lisp, getting symbols
  right is just too difficult for mere mortals (more so when using anything
  other than readtable-case :upcase), so to get them right, people resort
  to various hacks, the _best_ of which is using strings to refer to the
  foreign object and a symbol to hold onto the reference in the Lisp world,
  but that's comparatively inconvenient, and the symbol won't be _created_
  from the foreign name, for the obvious reasons.  in a lower-case Lisp,
  you _may_ use the symbol directly, but now it has disadvantages that you
  can see, because they aren't overshadowed by the _disadvantages_ of
  case-mangling in Common Lisp, so you can see the _advantages_ of using
  strings to name foreign objects with funny names, _plus_ you get the
  predictable results when you try to create the symbol-name yourself.
  thus, an upcasing Lisp will present self-defeating inconveniences that
  completely destroy the advantages of case-insensitivity, while a case-
  preserving lower-case Lisp will present _encouragement_ to use the much
  richer set of available symbol names, instead of the stupid names that
  particularly Windowsized C++ use to look like mangled symbol names even
  before the C++ mangler gets at them.

#:Erik
From: Rob Warnock
Subject: Re: newbie Lisp question
Date: 
Message-ID: <8adeoq$je2s8$1@fido.engr.sgi.com>
Erik Naggum  <····@naggum.no> wrote:
+---------------
| * Tim Bradshaw <···@cley.com>
| | While I appreciate that CL probably does need to talk with these infested
| | languages, and thus presumably will in due course become fully studly
| | itself, I find the prospect sad.
| 
|   I don't think this will happen, but I think it's _less_ likely to happen
|   with a lower-case Lisp than an upper-case Lisp.
+---------------

That's been my experience with using a few implementations of Scheme
which are both [contrary to the standard] case-sensitive and lower-case
for all the built-in symbols. People still use hyphens instead of
underscore or studly caps. In fact, case is almost a non-issue *except*
when (1) interfacing to C code or (2) using "read" on external files
produced by some other program.


-Rob

-----
Rob Warnock, 41L-955		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043
From: Tim Bradshaw
Subject: Re: newbie Lisp question
Date: 
Message-ID: <ey3put1ljdd.fsf@cley.com>
* Rob Warnock wrote:

> That's been my experience with using a few implementations of Scheme
> which are both [contrary to the standard] case-sensitive and lower-case
> for all the built-in symbols. People still use hyphens instead of
> underscore or studly caps. In fact, case is almost a non-issue *except*
> when (1) interfacing to C code or (2) using "read" on external files
> produced by some other program.

I can think of two reasons for this. Firstly if there exist
effectively case-insensitive implementations to which you might want
to port you have a strong incentive to write in a sane way.  Secondly
studliness seems to be a slow-developing disease -- the first C system
I saw that was seriously infected was X, although I'm sure there were
earlier ones.

More seriously, the point about hyphens warding it off is a pretty
good counterargument.

--tim
From: Tim Bradshaw
Subject: Re: newbie Lisp question
Date: 
Message-ID: <ey33dq1ul1c.fsf@cley.com>
* nicknews  wrote:

> ( defmacro defMyHashThing (name)
>    `(defun make-,name () (make-hash-table)))

You want something like:

	`(defun ,(intern (format nil "~A-~A"
	  	           (symbol-name :make)
	                   (symbol-name name))) ...)

The deviousness with symbol-name is an attempt to prevent either the common
problem of:

	(intern (format nil "~A-~A" :make name))

which doesn't do what you probably want if *print-case* is :downcase,
or the more obscure problem (perhaps never a problem in ANSI CL):

	(intern (format nil "MAKE-~A" (symbol-name name)))

which will do something unexpected in Allegro in case-sensitive-lower mode.

I'm not sure this works in *all* cases, though I think it does.

--tim
From: Marco Antoniotti
Subject: Re: newbie Lisp question
Date: 
Message-ID: <lwwvnc2k9p.fsf@parades.rm.cnr.it>
········@ptcstudios.com writes:

> I am trying to make a macro which creates functions, but I do not know
> how to create a the symbol to be used in the expanded code.
> 
> Example:
> 
> ( defmacro defMyHashThing (name)
             ^^^^^^^^^^^^^^

Please! No Java or C++ stuff here.  def-my-hash-thing is way better :)

>    `(defun make-,name () (make-hash-table)))
> 
> When I run macroexpand on this I get:
> 
> : (macroexpand-1 '(defMyHashThing foo))
> 
> (DEFUN MAKE- FOO NIL (MAKE-HASH-TABLE))
> 
> Note that a space is inserted between "make-" and "foo".  The macro
> will not put the "make-" and the "foo" together, so only a function
> called "make-" is defined when the macro is evaluated.

You need to actually create a name for the function (i.e. you need to
create a symbol).  This name is *not* a string.  It is much more.
You need to do

	(defmacro def-my-hash-thing (name)
           (let ((make-name (intern (concatenate 'string "MAKE-"
                                                 (string name)))))
              `(defun ,make-name () (make-hash-table))))

You may wornder why you need to do a thing which in Tcl you'd do
simply by concatenation.

The point is that in CL you are *not* using strings as your basic
structure, instead you use more sophisticated objects.

Cheers


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Daniel Barlow
Subject: Re: newbie Lisp question
Date: 
Message-ID: <871z5kaqn5.fsf@tninkpad.telent.net>
Marco Antoniotti <·······@parades.rm.cnr.it> writes:

> ········@ptcstudios.com writes:
> > ( defmacro defMyHashThing (name)
>              ^^^^^^^^^^^^^^
> 
> Please! No Java or C++ stuff here.  def-my-hash-thing is way better :)

Perhaps define-my-hash-thing, even

I realise that this is a style issue, and thus religious.  I mostly
attempt to follow the church of Pitman/Norvig as described in
http://www.norvig.com/luv-slides.ps, and most of the rest of this post
is merely to provide a context for recommending that anyone who hasn't
read it does so.

Page 98 of that document is the one to which I refer here:

| - Minimize abbreviations
|
|   Most words have many possible abbreviations but only one correct
|   spelling.  Spell out names so that they are easier to read,
|   remember, and find.


A completely tangential debate that we could have: they recommend
"verb-noun" function names rather than "noun-verb" -

frob-volume-control
call-cthulu

However, this doesn't really gel with, say, the PATHNAME functions, or
the accessors that defstruct generates, which are noun-verb.  I more
or less standardized on noun-verb despite Norvig/Pitman, figuring that
it didn't really matter that much provided I was consistent.

cthulu-invoke
volume-control-frob
volume-control-set

-dan
From: Tim Bradshaw
Subject: Re: newbie Lisp question
Date: 
Message-ID: <ey31z5j7j98.fsf@cley.com>
* Daniel Barlow wrote:

> However, this doesn't really gel with, say, the PATHNAME functions, or
> the accessors that defstruct generates, which are noun-verb.  

No they aren't, they're noun-noun compounds (pathname-directory, say
or foo-slot).

--tim