Re: [stack] possibilities for macros in a typed language

"Christopher Diggins" <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
On Fri, Feb 22, 2008 at 3:53 AM, John Nowak <[email protected]> wrote:
> Recently, I've been thinking about what sort of macro system might be
> suitable for a typed concatenative language. For this discussion, I'll
> assume a language like Cat minus any form of locals/variables. I'll
> call this hypothetical language 'Kitten' from this point on.

I had been calling Cat + locals Kitten at one point, but this is a
minor detail.

> Adding macros to Kitten seems fairly easy at first as the syntax is
> easily representable as a list and there are no variables to get in
> the way. Given that adding macros is fairly easy, it seems worth doing
> if they'd be truly useful.
>
> But are they?

Yes.

> In Lisp, macros are most commonly used for two reasons.
> The first is a lack of a concise syntax for anonymous functions, but
> this isn't an issue in Kitten. The second is dealing with bindings and
> binding constructs (SET!, etc), but this also isn't an issue. There
> are other uses of macros, but these two probably comprise 90% of the
> use cases.
>
> What other uses then might macros have in Kitten? One use I've come up
> with is allowing a way to write constructs that would otherwise be un-
> typeable.
>
> For an example, the m combinator 'dup i' cannot be assigned
> a type

Depends on your type system. In Cat "dup apply" has the type "(A (A (B
-> C) -> D) -> D)"

> for the same reason that '\x -> x x' cannot be assigned a type
> in Haskell; it requires the construction of an infinite type. (Cat's
> version of 'i' is called 'apply' I believe.)

The problem with Haskell is the lack of inference for inner forall
polymorphism.

> Even though 'dup i' isn't typeable, expressions like '[swap] [swap] i'
> and '[dup] [dup] i' are. Accordingly, we could define a macro like
> '[$A] m => [$A] [$A] i' that would work with quote literals. Such a
> macro is writable in a simple declarative system similar to Diggins's
> MetaCat (http://www.cat-language.com/metacat.html), although I believe
> MetaCat isn't currently usable for such things.

Currently the only thing preventing this is that "m" has to already be
predefined, a MetaCat macro can't define new instructions. I think I
may abolish that rule however.

> Another deficiency of the type system is a lack of number
> parameterized types. As such, you can't write a function like 'ndup'
> that duplicates the top N values on the stack. With an appropriate
> macro system however, you could expand '3 ndup' to a typeable
> construct. You would need something more powerful than MetaCat to do
> so however.

That is true, but it would be a very minor hack to improve the MetaCat
system to fix this. This is a very interesting idea!
The lack of parameterized types in Cat is a huge thorn in its paw.
Using macros we can side-step the issue by generating code.

The only problem I forsee is that programmers might type things like
"250 ndup" which would possibly bring the type-system to its knees,
because of the inherent complexity of typing massive stacks. The other
solution is to introduce fixed size type vectors.

> Optimization is another use of macros (as MetaCat shows). Slava Pestov
> recently walked me through some of the more interesting use cases of
> macros for optimization in Factor as well; 'case' is a good example.
>
> There are of course additional, more complex uses. One example would
> be a macro that translates code that uses locals to code that's
> pointfree. Another might be pattern matching. It's not clear if there
> are sufficiently many of such use cases to warrant the addition of a
> macro system as opposed to simply adding a few additional core
> syntactic constructs.
>
> There are obviously downsides to macros as well. Firstly, you
> sacrifice something in terms of concatenativity. For example, 'A B C
> D' might not be decomposable into 'A B' and 'C D' if macros are
> involved.

Type-checking is usually done after macro expansion.

> You also lose something in terms of consistency as
> constructors like 'm' would only be usable with function literals and
> not functions passed at runtime.
>
> Finally, you lose the "everything is
> a function" aspect of Kitten. In Kitten, even the literal '3' is
> really a function with the type 'A -> A int'. Similarly, '[dup]' is a
> function with the type 'A -> A (B c -> B c c)'.
> Macros eliminate this property,
>
> Macros are a huge design space. It seems to me that there are
> essentially four possibilities for such a system in Kitten:
>
> 1. Offer a MetaCat-like system, perhaps with some additional
> expressivity. This covers a fair chunk of the optimization cases very
> simply and it's declarative nature means that you don't need to write
> macros that cooperate with the type system. (Of course the result of
> the rewriting needs to be typeable.) It also allows for 'm' and
> perhaps other more difficult combinators (condnestrec?) to be
> integrated, at least when dealing with literals.
>
> 2. Offer a somewhat Lisp-like system where macros are pure functions
> of the type '[parse-entity] -> [parse-entity]'. This allows more
> flexibility than the MetaCat system, although pointfree syntactic
> manipulation is likely to be more complicated in practice. It is also
> likely to be a good deal more verbose as you'll either need to be
> deconstructing and reconstructing parse-entity sums or casting into
> and out of some universal type.
>
> 3. Take the Factor approach and offer proper parse words and
> everything derivable from them. Again, this seems like even more
> flexibility at the cost of even more complexity. I'm not too
> interested in this approach for a language like Kitten; it makes a lot
> of sense for Factor though.
>
> 4. Offer no macro system whatsoever as the possibilities aren't worth
> the downsides. Something like MetaCat would be integrated directly
> into the system for purposes of optimization only and wouldn't be
> exposed to the user.
>
> Of course, you could always just use Joy and get runtime macros for
> free!

If it is available at runtime then "macro" is the wrong term. You are
then describing a reflection facility.

> Many thanks if you've managed to keep reading this long. If anyone has
> thoughts on what an ideal macro system for a Kitten-like language
> might be, or even if such a system is useful, they'd be much
> appreciated.
>
> - John

Cheers,
Christopher
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.