Hello,
I joined my report but it is still not complete, I will send you a complete version later.
Allow me to comment your proposal (I know the tutorial I sent was not very clear, and I have to make it clearer) :

2006/6/8, Torsten Anders <[EMAIL PROTECTED]>:
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.

This can be done as I will show you here under. BUT you cannot redefine the control structures already existing in Oz. When discussing with Peter, we agreed that being able to redefine if .. then .. else for example; will only introduce ambiguities.
Notice that defining myif..then..end is allowed.

  * 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).

This is not sure to work for now, as all the Oz syntax (in particular the class syntax) is not supported by the macro hygienic renaming system. As soon as it will be you will be allowed to define such macro.
You would have to define a macro like
macro newclass ClassName with [listOfAttributes] end
which contain some executable code to generate the accessors and init function, by going through the list of attribute.
 

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.

Well, you can use ANY Oz symbol as separator, including operators, atoms, keyword, whatever. It was a bit fuzzy sorry. BUT macro MUST begin with an atom, which is not a keyword of the language.
This is a convention we made, Peter and I. The definition of the macro should respect the block syntax keyword..end
So redefining the meaning of '+' is not possible, but we fought this capabilities would only be more confusing to the user.

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:

That is a nice trick :)
- Afficher le texte des messages précédents -

%% 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.

Yes it is a lack of the system, due to the incomprehensibility of the compiler for a young student like me.
Anyway the researchers here are considering the possibility of manipulating syntax tree inside a macro declaration. With this possibility you would be able to act on you arguments, whithout evaluating them.
They are also planning variable-arguments macro.

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

You get it !

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...

You can use '{' if you 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]

you can define your macro like that:
defun  FunName( Args ) end
with Args being a list when calling the macro, as a varying number of arguments is not accepted.
I hope it's what you would like to have ? Maybe I didn't understood ?

        ----------------------

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?

Sorry about that, but we I must be coherent with the Oz syntax invariant of keyword..end.
Note that most of the problems in implementing macro are due
1° to the f***ing Oz compiler
2° to the Oz syntax; in which there is almost no special characters left to use in macro syntax !

* 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.

Macro import does not work for now, we are considering several ways to do it, I won't forget your advice.

* 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).

It will probably become emacro and smacro (_expression_ macro as fmacro, and statement macro as pmacro). Try pronouncing 'pimacro' and 'èfmacro' (?)
Any suggestion is welcome !

This mail become rather lengthy, sorry. 

No ! Thanks for the comments and proposals ! I'm very grateful to you ! I hope I succeeded in answering your questions.

Best regards,
Olivier Tonglet.
_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to