From: Jeremy Smith
Subject: C++ style class usage in Lisp
Date: 
Message-ID: <Xns972625EC4B19Djeremyalansmithsofth@62.253.170.163>
Hi all,

When I write object oriented code in C++, sometimes I want to wrap a lot of   
global C functions and variables into a class. I can do this by declaring 
the class before it, and either putting all those functions and variables 
inside the class definition, or leaving the functions outside the 
definition block, and preceding their prototypes with "Class::".

The advantage of C++ here is that I don't have to manually go through every 
variable assignment and precede it with either "with-slots" or just change 
every variable to a slot, and the class type name. This would take hours.

My question is: In Lisp, do I have to do this manually, or is there a way 
to create a class surrounding a block of functions and some global 
variables, with just a few minutes' work?

I imagine it can be done with macros, but if not, it seems odd that it 
can't be this flexible.

I tried to look on Google Groups for information on this, but I couldn't 
think of any search query which would have given me the information I want.

Thanks for any tips,

Jeremy.

From: Jeremy Smith
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <Xns9726296069F4Ajeremyalansmithsofth@62.253.170.163>
Jeremy Smith <············@decompiler.org> wrote in
·········································@62.253.170.163: 

> Hi all,
> 
> When I write object oriented code in C++, sometimes I want to wrap a
> lot of   global C functions and variables into a class. I can do this
> by declaring the class before it, and either putting all those
> functions and variables inside the class definition, or leaving the
> functions outside the definition block, and preceding their prototypes
> with "Class::". 
> 

I've done it again, I posted too soon so I'd better clear 2 things up.

1 is the I've read the classes chapter in Practical Common Lisp, and 

2 is an example, to clear up ambiguity in my post. I've used my own C 
indentation style, so please no criticism about that.

This is the code in C++. It doesn't really do anything, but it's an 
example.
-------
#include <string>
#include <vector>
using namespace std;

vector<string>Tokens;
int TokenCount;

void AddToken(string token)
{
  Tokens.push_back(token);
  TokenCount++;
}
-------

Now, having written about 7000 lines of this type of thing, I now want to 
wrap it like so:

-------
#include <string>
#include <vector>
using namespace std;

class Tokeniser
{
  private:
  vector<string>Tokens;
  int TokenCount;

  void AddToken(string token)
  {
    Tokens.push_back(token);
    TokenCount++;
  }
}
-------

This is quick, easy, and painless. Whether it's the "right" thing to do 
is not part of my question.

At the moment, I have a decompiler which uses global variables, due to 
the annoyance of typing a variable name without something like this:

  (setf (slot-value *car* 'license) "FOOBAR")

Whenever the decompiler wants to call back to itself, I have to put every 
global variable in a big list, and then pop it onto a stack until it's 
finished calling itself. It works fine, but it's not desirable. It's not 
the "right" thing to do, but it would take hours to rewrite 7000 lines of 
global variable references to reference a single class, and I would also 
have to rewrite every function header - of which there are several 
hundred.

My question is, is there a way to do this in Lisp that is also quick, 
easy and painless?

I do love Lisp, and I'm very productive in it, but it does seem a bit 
verbose sometimes.

Thanks,

Jeremy.
From: Pisin Bootvong
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <1134028728.280484.272650@o13g2000cwo.googlegroups.com>
If those groups of variables and functions are global then you are
actually using a class as a namespace.
Use package instead, as Pascal Bourguignon has replied.

(defpackage :namespace-class
  (:use :common-lisp)
  (:export :add-token))
(IN-PACKAGE :namespace-class)
(DEFVAR *tokens* '())
(DEFVAR *token-count* 0)
(DEFUN add-token (token)
    (push token *tokens*)
    (incf *token-count*))


Then in other package you can just call it as

(namespace-class:add-token "a token")

In other words, in language such as Java/C# where a method must always
belong to a class. Static method (what you are using) is a way to
simulate the lack of namespace.

If you also want the ability to switch which implementation to call at
run times, which is Singleton pattern in OO term, Then you'll need to
use CLOS.
From: Pascal Bourguignon
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <87pso86wxq.fsf@thalassa.informatimago.com>
Jeremy Smith <············@decompiler.org> writes:
> [...]
> At the moment, I have a decompiler which uses global variables, due to 
> the annoyance of typing a variable name without something like this:
>
>   (setf (slot-value *car* 'license) "FOOBAR")
>
> Whenever the decompiler wants to call back to itself, I have to put every 
> global variable in a big list, and then pop it onto a stack until it's 
> finished calling itself. It works fine, but it's not desirable. It's not 
> the "right" thing to do, but it would take hours to rewrite 7000 lines of 
> global variable references to reference a single class, and I would also 
> have to rewrite every function header - of which there are several 
> hundred.
>
> My question is, is there a way to do this in Lisp that is also quick, 
> easy and painless?
>
> I do love Lisp, and I'm very productive in it, but it does seem a bit 
> verbose sometimes.


And you can define symbol-macros and macros to transform global
dynamic variables into slots, and defun into defmethods with an
additionnal self or this argument, but I doubt it'll be worth the
confusion.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You question the worthiness of my code? I should kill you where you
stand!"
From: Brad Might
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <1134075285.300738.140850@g44g2000cwa.googlegroups.com>
Jeremy Smith wrote:
> Jeremy Smith <············@decompiler.org> wrote in
> ·········································@62.253.170.163:
>

>
> Now, having written about 7000 lines of this type of thing, I now want to
> wrap it like so:
>

>
> My question is, is there a way to do this in Lisp that is also quick,
> easy and painless?
>
> I do love Lisp, and I'm very productive in it, but it does seem a bit
> verbose sometimes.
>

I'm not very clear on what it is you are trying to accomplish. Maybe
you could show us some of that lisp code?
I suspect that if you have 7000 lines, all very similar, you need to
learn more about macros. If you find yourself typing the same pattern
over and over again (where count > 1) then you have stumbled across the
very possible use of a macro. Ideally you program a macro with your
pattern and then provide a list of items which customize it.
Alternatively, with lisp, often times you don't need all those
repetitions and the code can be structured in such a way to handle all
those cases with 1 occurence of the code instead of 7000.
From: Jeremy Smith
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <Xns9727D93B9D2Cjeremyalansmithsofth@62.253.170.163>
> I'm not very clear on what it is you are trying to accomplish. Maybe
> you could show us some of that lisp code?

Well, the decompiler has a lot of functions that generate output tokens. 
I could pass the token list in as an argument to every function, but this 
would look ugly, would take hours to implement, and wouldn't make the 
code any tidier.

What I'm trying to accomplish, therefore, is:

    	*To make a few global variables available to the decompiler's  
functions, like a class
    	*To make the class re-entrant, so that when you create a new one 
(the decompiler is recursive, it calls itself), it gets a new variable 
space which doesn't affect the old one
    	*C++ class scope syntax, where a global variable inside one of the 
above class functions doesn't have to be prefixed with a call, or a class 
name, or parentheses in any way. I think this excludes macros, which from 
what I can tell, need parentheses.

> I suspect that if you have 7000 lines, all very similar, you need to
> learn more about macros. If you find yourself typing the same pattern
> over and over again (where count > 1) then you have stumbled across
> the very possible use of a macro.

I've never seen the need for macros where a function will do. I use 
functions wherever possible, and the occasional macro (such as -> for 
hashmap access), and the program is very compact. For instance, the C++ 
version (which is now less functional than this one) was about 27,000 
lines, and this is 1/4 of that, *because* of my extensive use of 
functions.

It's a complex program.

I admit though, that a couple of thousand lines are static data, and 
could be split off into a datafile.

> Ideally you program a macro with
> your pattern and then provide a list of items which customize it.
> Alternatively, with lisp, often times you don't need all those
> repetitions and the code can be structured in such a way to handle all
> those cases with 1 occurence of the code instead of 7000.

I'm generally a bit wary of macros, because I seem to be able to do most 
of it from functions. I haven't read On Lisp yet, but I will soon.

Thanks for the help!

Jeremy.
From: Brad Might
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <1134229904.013674.199160@g47g2000cwa.googlegroups.com>
Jeremy Smith wrote:
>
>
> > I suspect that if you have 7000 lines, all very similar, you need to
> > learn more about macros. If you find yourself typing the same pattern
> > over and over again (where count > 1) then you have stumbled across
> > the very possible use of a macro.
>
> I've never seen the need for macros where a function will do. I use
> functions wherever possible, and the occasional macro (such as -> for
> hashmap access), and the program is very compact. For instance, the C++
> version (which is now less functional than this one) was about 27,000
> lines, and this is 1/4 of that, *because* of my extensive use of
> functions.
>

I'm suggesting that rather than simple substitution macros a la C/C++,
you have some macros which do some code generation for you. If you have
that much code that is very similar, perhaps a macro or too could be
used such that you could use the macro to generate the common parts.
Therefore, when sweeping changes such as this might occur, then you
would merely have to change the macro definition and recompile.
Without an example of what you're trying to do, its hard to provide an
example which makes sense for you. I was hoping to see 2 or 3 of your
functions with common code which we could then macro-ize for you.

I see that the info on the binding of globals has been helpful to you,
maybe that's all you needed but i suspect there's a lot more room for
cleanup and compacting your code.
From: Thomas A. Russ
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <ymipso2nr7b.fsf@sevak.isi.edu>
Jeremy Smith <············@decompiler.org> writes:

> 
> > I'm not very clear on what it is you are trying to accomplish. Maybe
> > you could show us some of that lisp code?
> 
> Well, the decompiler has a lot of functions that generate output tokens. 
> I could pass the token list in as an argument to every function, but this 
> would look ugly, would take hours to implement, and wouldn't make the 
> code any tidier.
> 
> What I'm trying to accomplish, therefore, is:
> 
>     	*To make a few global variables available to the decompiler's  
> functions, like a class

OK.  You have a couple of options here.  One is to use a parameter-block
approach, where you package all of this information up into an object
and just pass that object.

The other, perhaps simpler approach is to use special variables.  That's
probably what I would do.

>     	*To make the class re-entrant, so that when you create a new one 
> (the decompiler is recursive, it calls itself), it gets a new variable 
> space which doesn't affect the old one

Use LET to bind the special variable values.  That uses dynamic binding
to make the new values visible to subsequent calls, and when you exit
the LET block, restores the old bindings.

>     	*C++ class scope syntax, where a global variable inside one of the 
> above class functions doesn't have to be prefixed with a call, or a class 
> name, or parentheses in any way. I think this excludes macros, which from 
> what I can tell, need parentheses.

This is really a non-issue.
But if you use special variables, you just refer to them as variable
names, although convention dictates that you name them like *THIS*.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Geoffrey Summerhayes
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <lz%lf.8800$kt5.650145@news20.bellglobal.com>
"Jeremy Smith" <············@decompiler.org> wrote in message 
·········································@62.253.170.163...
>
> At the moment, I have a decompiler which uses global variables, due to
> the annoyance of typing a variable name without something like this:
>
>  (setf (slot-value *car* 'license) "FOOBAR")
>
> Whenever the decompiler wants to call back to itself, I have to put every
> global variable in a big list, and then pop it onto a stack until it's
> finished calling itself. It works fine, but it's not desirable. It's not
> the "right" thing to do, but it would take hours to rewrite 7000 lines of
> global variable references to reference a single class, and I would also
> have to rewrite every function header - of which there are several
> hundred.
>

The other posts talk about packages, but for myself, I'm curious about
why the list needs creating, since you're using specials why not just
use LET and allow lisp to handle it?

(defparameter *foo* 6)

(defun print-foo(label)
  (format *standard-output* "~&~A:~A~%" label *foo*))

(defun foo(x y z)
  (print-foo 'foo-1)
  (let ((*foo* x))
    (print-foo 'foo-2)
    (setf *foo* y)
    (print-foo 'foo-3))
  (print-foo 'foo-4)
  (setf *foo* z)
  (print-foo 'foo-5))

(defun bar (a b c d)
  (print-foo 'bar-1)
  (let ((*foo* a))
    (print-foo 'bar-2)
    (foo b c d)
    (print-foo 'bar-3))
  (print-foo 'bar-4))


CL-USER 6 > (bar 1 2 3 4)
BAR-1:6
BAR-2:1
FOO-1:1
FOO-2:2
FOO-3:3
FOO-4:1
FOO-5:4
BAR-3:4
BAR-4:6
NIL

--
Geoff
From: Larry Clapp
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <slrndphee6.b1n.larry@theclapp.ddts.net>
On 2005-12-08, Jeremy Smith <············@decompiler.org> wrote:
> Jeremy Smith <············@decompiler.org> wrote in
> ·········································@62.253.170.163: 
>> When I write object oriented code in C++, sometimes I want to wrap
>> a lot of   global C functions and variables into a class. I can do
>> this by declaring the class before it, and either putting all those
>> functions and variables inside the class definition, or leaving the
>> functions outside the definition block, and preceding their
>> prototypes with "Class::". 
>
> I've done it again, I posted too soon so I'd better clear 2 things
> up.
>
> 1 is the I've read the classes chapter in Practical Common Lisp, and 
>
> 2 is an example, to clear up ambiguity in my post. I've used my own
> C indentation style, so please no criticism about that.
>
> This is the code in C++. It doesn't really do anything, but it's an
> example.
> -------
> #include <string>
> #include <vector>
> using namespace std;
>
> vector<string>Tokens;
> int TokenCount;
>
> void AddToken(string token)
> {
>   Tokens.push_back(token);
>   TokenCount++;
> }
> -------
>
> Now, having written about 7000 lines of this type of thing, I now want to 
> wrap it like so:
>
> -------
> #include <string>
> #include <vector>
> using namespace std;
>
> class Tokeniser
> {
>   private:
>   vector<string>Tokens;
>   int TokenCount;
>
>   void AddToken(string token)
>   {
>     Tokens.push_back(token);
>     TokenCount++;
>   }
> }
> -------
>
> This is quick, easy, and painless. Whether it's the "right" thing to do 
> is not part of my question.
>
> At the moment, I have a decompiler which uses global variables, due to 
> the annoyance of typing a variable name without something like this:
>
>   (setf (slot-value *car* 'license) "FOOBAR")
>
> Whenever the decompiler wants to call back to itself, I have to put every 
> global variable in a big list, and then pop it onto a stack until it's 
> finished calling itself. It works fine, but it's not desirable. It's not 
> the "right" thing to do, but it would take hours to rewrite 7000 lines of 
> global variable references to reference a single class, and I would also 
> have to rewrite every function header - of which there are several 
> hundred.
>
> My question is, is there a way to do this in Lisp that is also quick, 
> easy and painless?

By "global variable" I assume you mean a DEFVAR'd or DEFPARAMETER'd
variable:

(defvar v1)
(defvar v2)
(defvar v3)

In which case you should be able to say

(defun call-compiler (v1 v2 v3)
  (more code))

or do the same thing with LET:

  ... code ...
  (let ((v1 'new-v1-val)
	(v2 'new-v2-val)
	(v3 'new-v3-val))
    ... recursive compiler code ...)
  ... v1 v2 v3 have their old values here ...
      
Since v1, v2, and v3 are special, putting them on the arg list of the
function (or in the LET) binds new values to them, and when the
function (or the LET) exits, their old values are restored.  This
automatically accomplishes what you're already doing: putting the old
values on a list, assigning new values, and calling the code
recursively.

Example (not using the usual *variable* convention for specials):

  CL-USER> (defvar a)

  A
  CL-USER> (defvar b)

  B
  CL-USER> (setq a 'a-val)

  A-VAL
  CL-USER> (setq b 'b-val)

  B-VAL
  CL-USER> (defun print-a-b () 
	     (format t "a is ~S, b is ~S~%" a b))

  PRINT-A-B
  CL-USER> (print-a-b)
  a is A-VAL, b is B-VAL
  NIL
  CL-USER> (defun call-compiler (a b) 
	     (print-a-b))

  CALL-COMPILER
  CL-USER> (call-compiler 'new-a 'new-b)
  a is NEW-A, b is NEW-B
  NIL
  CL-USER> a

  A-VAL
  CL-USER> b

  B-VAL

See?

On the other hand, if you've written a decompiler and 7k lines of
Lisp, you probably know about special variables, so maybe I'm missing
something.  :)  In which case, of course, please enlighten me.

-- Larry
From: Jeremy Smith
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <Xns9727D9344AC9Fjeremyalansmithsofth@62.253.170.163>
>> My question is, is there a way to do this in Lisp that is also quick,
>> easy and painless?
> 
> By "global variable" I assume you mean a DEFVAR'd or DEFPARAMETER'd
> variable:
> 
> (defvar v1)
> (defvar v2)
> (defvar v3)
> 
> In which case you should be able to say
> 
> (defun call-compiler (v1 v2 v3)
>   (more code))
> 
> or do the same thing with LET:
> 
>   ... code ...
>   (let ((v1 'new-v1-val)
>      (v2 'new-v2-val)
>      (v3 'new-v3-val))
>     ... recursive compiler code ...)
>   ... v1 v2 v3 have their old values here ...
>       
> Since v1, v2, and v3 are special, putting them on the arg list of the
> function (or in the LET) binds new values to them, and when the
> function (or the LET) exits, their old values are restored.  This
> automatically accomplishes what you're already doing: putting the old
> values on a list, assigning new values, and calling the code
> recursively.
> 
> Example (not using the usual *variable* convention for specials):
> 
>   CL-USER> (defvar a)
> 
>   A
>   CL-USER> (defvar b)
> 
>   B
>   CL-USER> (setq a 'a-val)
> 
>   A-VAL
>   CL-USER> (setq b 'b-val)
> 
>   B-VAL
>   CL-USER> (defun print-a-b () 
>           (format t "a is ~S, b is ~S~%" a b))
> 
>   PRINT-A-B
>   CL-USER> (print-a-b)
>   a is A-VAL, b is B-VAL
>   NIL
>   CL-USER> (defun call-compiler (a b) 
>           (print-a-b))
> 
>   CALL-COMPILER
>   CL-USER> (call-compiler 'new-a 'new-b)
>   a is NEW-A, b is NEW-B
>   NIL
>   CL-USER> a
> 
>   A-VAL
>   CL-USER> b
> 
>   B-VAL
> 
> See?
> 
> On the other hand, if you've written a decompiler and 7k lines of
> Lisp, you probably know about special variables, so maybe I'm missing
> something.  :)  In which case, of course, please enlighten me.
> 
> -- Larry
> 

Hi,

Well, I understand about special variables and scoping, as I read about  
them in Practical Common Lisp.

There are about 30 special variables which are global and contain 
information which could be useful to any function. Passing all these down 
the chain from decompile() to check-file() as arguments, would be a 
nightmare, and thus special variables are necessary.

Your solution would be fine if the decompiler was just a single function.  
However, when it's decompiling, the filename might be needed by a function 
(let's call it check-file) which is about 4 calls deep. Every function on 
the way to set-value will have to accept the filename data, and pass it 
along.

I suppose you could argue that I must be writing this program in the wrong 
way, if I need to pass data all around the place. But I can't see any way 
around it.

Cheers,

Jeremy.
From: jayessay
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <m3r78lj0ir.fsf@rigel.goldenthreadtech.com>
Jeremy Smith <············@decompiler.org> writes:

> >> My question is, is there a way to do this in Lisp that is also quick,
> >> easy and painless?
...
> > Since v1, v2, and v3 are special, putting them on the arg list of the
> > function (or in the LET) binds new values to them, and when the
> > function (or the LET) exits, their old values are restored.  This
> > automatically accomplishes what you're already doing: putting the old
> > values on a list, assigning new values, and calling the code
> > recursively.

> Well, I understand about special variables and scoping, as I read about  
> them in Practical Common Lisp.

You may need to think them through a bit more, because...

> Your solution would be fine if the decompiler was just a single function.  
> However, when it's decompiling, the filename might be needed by a function 
> (let's call it check-file) which is about 4 calls deep. Every function on 
> the way to set-value will have to accept the filename data, and pass it 
> along.

nothing you've said here affects the suggestion.  The binding of the
special holds for _dynamic_ scope of the variable binding - the entire
call tree rooted at the binding.  So, binding special *S* in function
F and then having F call G call H call G call A call B ... will have
everyone of these invocations seeing the value of *S* bound by F.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Jeremy Smith
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <Xns97281443FC57jeremyalansmithsofth@62.253.170.163>
jayessay <······@foo.com> wrote in
···················@rigel.goldenthreadtech.com: 

>> Well, I understand about special variables and scoping, as I read
>> about  them in Practical Common Lisp.
> 
> You may need to think them through a bit more, because...
> 
>> Your solution would be fine if the decompiler was just a single
>> function.  However, when it's decompiling, the filename might be
>> needed by a function (let's call it check-file) which is about 4
>> calls deep. Every function on the way to set-value will have to
>> accept the filename data, and pass it along.
> 
> nothing you've said here affects the suggestion.  The binding of the
> special holds for _dynamic_ scope of the variable binding - the entire
> call tree rooted at the binding.  So, binding special *S* in function
> F and then having F call G call H call G call A call B ... will have
> everyone of these invocations seeing the value of *S* bound by F.

Well, that's very handy!

I just read in Practical CL (chapter Variables, which I've read before) 
that you can redefine a special variable to have scope to the call tree 
below this function, as you said, using 'let' to redefine it temporarily.

This suits my needs, so thanks a lot for that. I wouldn't have known 
about it though, as it seems entirely non-obvious to me to re-bind a 
variable using let!

Thanks to everyone for their help. I thought my original posting was a 
bit long-winded and not explained well enough, so I'll try and be more 
careful next time.

Jeremy.
From: jayessay
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <m3irtwiy5b.fsf@rigel.goldenthreadtech.com>
Jeremy Smith <············@decompiler.org> writes:

> jayessay <······@foo.com> wrote in
> ···················@rigel.goldenthreadtech.com: 
> 
> >> Well, I understand about special variables and scoping, as I read
> >> about  them in Practical Common Lisp.
> > 
> > You may need to think them through a bit more, because...
> > 
> >> Your solution would be fine if the decompiler was just a single
> >> function.  However, when it's decompiling, the filename might be
> >> needed by a function (let's call it check-file) which is about 4
> >> calls deep. Every function on the way to set-value will have to
> >> accept the filename data, and pass it along.
> > 
> > nothing you've said here affects the suggestion.  The binding of the
> > special holds for _dynamic_ scope of the variable binding - the entire
> > call tree rooted at the binding.  So, binding special *S* in function
> > F and then having F call G call H call G call A call B ... will have
> > everyone of these invocations seeing the value of *S* bound by F.
> 
> Well, that's very handy!

Indeed - that's why it's designed as it is.


> I just read in Practical CL (chapter Variables, which I've read before) 
> that you can redefine a special variable to have scope to the call tree 
> below this function, as you said, using 'let' to redefine it temporarily.

Which is an example of the given suggestion.  The thing to note is
that _any_ _binding_ of a special will behave in this way.  The notion
of _binding_, and the difference between lexical and dynamic binding
and how "special variables", i.e., those with _dynamic scope_ play
with this is something that newbies (especially those coming from
pedistrian static languages like c/c++/c#/java/etc.) often have
trouble getting their minds wrapped around.

The first order of approximation is to pretend that specials are just
"global" variables (as typically found in static things like
c/c++/c#/java/etc.)  But they absolutely are not the same thing.  And
the way they really work can be _stunningly_ useful.  For example,
think about this dynamic scoping and threaded applications.  It is not
an accident that (even though Lisp is not strictly functional) writing
multithreaded applications is far easier, simpler and intrinsically
more robust than just about anything else available.


> This suits my needs, so thanks a lot for that. I wouldn't have known
> about it though, as it seems entirely non-obvious to me to re-bind a
> variable using let!

Right - see above.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Pascal Bourguignon
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <87wtig6xbf.fsf@thalassa.informatimago.com>
Jeremy Smith <············@decompiler.org> writes:

> Hi all,
>
> When I write object oriented code in C++, sometimes I want to wrap a lot of   
> global C functions and variables into a class. I can do this by declaring 
> the class before it, and either putting all those functions and variables 
> inside the class definition, or leaving the functions outside the 
> definition block, and preceding their prototypes with "Class::".
>
> The advantage of C++ here is that I don't have to manually go through every 
> variable assignment and precede it with either "with-slots" or just change 
> every variable to a slot, and the class type name. This would take hours.
>
> My question is: In Lisp, do I have to do this manually, or is there a way 
> to create a class surrounding a block of functions and some global 
> variables, with just a few minutes' work?

There is a confusion in C++ between namespaces and classes.  Not so in
Common Lisp, where you have the two distinct concepts of class and
package.  So when you want to put a bunch of definitions in their own
namespace, you just define a package and prepend a IN-PACKAGE:

(defpackage :my-class-which-is-actually-a-namespace
  (:use :common-lisp))
(IN-PACKAGE :my-class-which-is-actually-a-namespace)


;; ... the definitions, like:
(defun example (x) ...)
(defvar *example* ...)



(IN-PACKAGE :cl-user)

(my-class-which-is-actually-a-namespace::example 
   my-class-which-is-actually-a-namespace::*example*)



Of course, you can also export these definitions:

(defpackage :my-class-which-is-actually-a-namespace
  (:use :common-lisp)
  (:export "*EXAMPLE*" "EXAMPLE"))
;;...

then you can use them without the package qualifier:

(defpackage :another-namespace
  (:use :common-lisp 
        :my-class-which-is-actually-a-namespace))
(in-package :another-namespace)

(example *example*)


Read  Chapter 11 -- Packages  of CLHS, or any other tutorial about
Common Lisp packages.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You can tell the Lisp programmers.  They have pockets full of punch
 cards with close parentheses on them." --> http://tinyurl.com/8ubpf
From: Jeremy Smith
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <Xns9726D333FAB0Fjeremyalansmithsofth@62.253.170.163>
> There is a confusion in C++ between namespaces and classes.  Not so in
> Common Lisp, where you have the two distinct concepts of class and
> package.  So when you want to put a bunch of definitions in their own
> namespace, you just define a package and prepend a IN-PACKAGE:
> 
[snip]
> Read  Chapter 11 -- Packages  of CLHS, or any other tutorial about
> Common Lisp packages.

Thanks for the help and the pointers. The package concept sounds ideal for 
my purposes, so I'll read on.

All the best,

Jeremy.
From: Thomas A. Russ
Subject: Re: C++ style class usage in Lisp
Date: 
Message-ID: <ymislt1opam.fsf@sevak.isi.edu>
Jeremy Smith <············@decompiler.org> writes:

> 
> Hi all,
> 
> When I write object oriented code in C++, sometimes I want to wrap a lot of   
> global C functions and variables into a class. I can do this by declaring 
> the class before it, and either putting all those functions and variables 
> inside the class definition, or leaving the functions outside the 
> definition block, and preceding their prototypes with "Class::".

Why do you want to do this?

> The advantage of C++ here is that I don't have to manually go through every 
> variable assignment and precede it with either "with-slots" or just change 
> every variable to a slot, and the class type name. This would take hours.
> 
> My question is: In Lisp, do I have to do this manually, or is there a way 
> to create a class surrounding a block of functions and some global 
> variables, with just a few minutes' work?

Yes.  Use DEFPACKAGE and IN-PACKAGE.
They don't belong in a class if they are meant to be global.

BTW, in C++ namespaces might be more appropriate.

-- 
Thomas A. Russ,  USC/Information Sciences Institute