Dear Tonglet,
Sorry for the late replay. I am most happy that there are macro
facilities underway for Oz!!
On 29.05.2006, at 17:57, tooli wrote:
nb1 : if you are interested in using/testing the pre-processor, or
reading the complete report, I can send it to you, as well as the
source code.
I would like to have a look at that.
Here are some thoughts on your proposal.
I am very much looking forward to define and use macros in my Oz
applications. When reading my comments, please bear in mind that I am
looking at your proposal mainly from a users perspective, and users can
be very demanding...
To be specific from the beginning, here are two macros I miss all the
time in Oz:
* I would like to redefine Oz' function definition syntax to allow for
functions with optional arguments and (optional) keyword arguments.
* I would like to define a class definition macro which beefs up
classes by reflective capabilities. For example, the macro should
implicitly define methods which return the attributes defined for a
class instance (attributes directly defined by the class or inherited
attributes). Also, the macro should implicitly define a method which
returns the init method record which would create a given object
instance (this requires analysing the init method definition, e.g., to
collect the default values for optional init method arguments).
These two cases can not be defined as procedures, because they extend
the syntax of Oz and therefore call for macro facilities. The first
macro would change/extend the syntax of procedure (and function)
definitions (which would also be reflected by procedure/function
application). The second macro would analyse the special syntax of
class definitions (or some equivalent).
So, I looked at your proposal and then tried to realise the first
macro, namely the definition (and application) of functions with
optional and keyword arguments. I am now presenting some of my tries
and ask you and the rest of the community whether there are perhaps
more suitable ways to address these requirements. I will even use your
macro facilities in a way which they do not support -- please let me
know about more suitable ways in these cases.
--------
I do understand that the syntax defined by your macros must consist in
literal Oz value (i.e. values with a textual representation such as
atoms or records). This implies, that macros can not use characters
like '{' or '}' (nor '[]', or all the infix operators defined by Oz).
Side note: having the full macro facilities of Lisp within Oz would
perhaps allow to turn these characters into macro characters
(http://www.lisp.org/HyperSpec/Body/sec_2-1-4-4.html) such that their
meaning can be programmed.
Consequently, {<something>} is no data structure which can be processed
somehow as macro argument. Besides, all function arguments are
mandatory in Oz: Oz' function application can not handle
optional/keyword arguments. Therefore, I surround all my function
arguments with a record (quasi my lambda list in Oz). So, my first
alternative syntax attempt for function definition looks like this:
%% The macro defun defines the function Foo with the mandatory argument
X,
%% the optional argument Y (defaults to 42) and the keyword argument z
(defaults to bla).
defun '{'Foo args(X Y#42 z:Z#bla)'}'
[X Y Z]
end
Here are some example calls for Foo
{Foo args(hi)} % -> [hi 42 bla]
{Foo args(hi there)} % -> [hi there bla]
{Foo args(hi z:there)} % -> [hi 42 there]
{Foo args(z:bar)} % Exception: no Args.1 given
Here comes some template how the macro defun could be defined (the
functions MakeDefaultVals and MakeAllVarDecls are not defined here, but
I hope the example is readable anyway).
pmacro defun '{' Name Args '}' Body end
Defaults = {MakeDefaultVals Args}
in
(| fun {Name MyArgs}
','{MakeAllVarDecls Defaults MyArgs}
in
Body
end |)
end
The comma is not part of your proposal and obviously inspired by Lisp.
I just did not find something in your proposal which does allow me to
process Args without evaluating it first: I want to process the _code_
bound to Args _before_ evaluating it later when the macro is called
(e.g. the variables in Args are not defined at all at the time when
MakeAllVarDecls is called). BTW: I did not find something like Lisps
,@<val> in your proposal either.
The function definition
defun '{'Foo args(X Y#42 z:Z#bla)'}'
[X Y Z]
end
is now macroexpands into this code
local
Defaults = args(2:24 z:bla)
in
fun {Foo MyArgs}
X = MyArgs.1
Y = {SelectArg 2 MyArgs Defaults}
Z = {SelectArg z MyArgs Defaults}
in
[X Y Z]
end
end
%% I use this function in the macro expansion
fun {SelectArg Feature Spec Defaults}
if {HasFeature Spec Feature}
then Spec.Feature
else Defaults.Feature
end
end
The syntax of my function definition and application is rather bulky.
Here are some alternative attempts (only the syntax, no macro def nor
expansion). The problem here is still that
{ <something> } can not be processed as data in the macro. So I try to
do without it (i.e. replace it by my own lambda list). Now, this
becomes eerily Lisp-like...
defun [Foo X optional Y#42 key z#Z#bla]
[X Y Z]
end
This function definition requires also function application to become a
macro
apply [Foo hi z#there] end %% -> [hi 42 there]
Next try:
defun f(Foo X Y#42 z:Z#bla)
[X Y Z]
end
apply f(Foo hi z:there) end %% -> [hi 42 there]
My favorite syntax would be the following. Yet, this is no legal Oz
record syntax: a record label can not be a function (yet?).
defun Foo(X Y#42 z:Z#bla)
[X Y Z]
end
apply Foo(hi z:there) end %% -> [hi 42 there]
----------------------
OK, to conclude here are a few further thoughts.
* According to your specification, macro must terminate with the
keyword 'end'. Most existing Oz keyword constructs do indeed have this
form. Still, there also exist predefined oz constructs which are not
terminated by 'end' (e.g. andthen, orelse). Should the macro facility
perhaps also allow for such constructs?
* Besides, could there perhaps be some alternative values allowed for
macro termination (i.e. instead of 'end'). My function application
macro 'apply <..> end' (see above) is af course a bit too verbose. For
example, I envy the SmallTalk guys for their concise way to define
blocks by [<some code>]. This syntax makes macros almost unnecessary --
just use first class functions for stuff like your macro unlike ;-) But
that would definitely be no Oz anymore ;-)
* You propose macros as a pre-processor facility. This pre-processing
is not specified in the program itself. I would prefer that a program
somehow imports its macros explicitly, so that the meaning of a program
is defined fully by the program itself.
* Are the keywords pmacro and fmacro the best choice? I agree that
keywords must be short, but
these keywords are hard to pronounce (e.g. all existing alphabetic Oz
keywords can be pronounced, cf.
http://www.mozart-oz.org/documentation/notation/
node2.html#chapter.lexical).
This mail become rather lengthy, sorry.
Best,
Torsten
--
Torsten Anders
Sonic Arts Research Centre • Queen's University Belfast
Frankstr. 49 • D-50996 Köln
Tel: +49-221-3980750
www.torsten-anders.de
strasheela.sourceforge.net
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users