From: Alessio Stalla
Subject: Macro design question
Date: 
Message-ID: <51afe9e6-f90d-4d98-9563-eb8201f9c246@r3g2000vbp.googlegroups.com>
Hello, I'd like to have opinions on the design of a DSL I'm working
on, in particular on a certain use of macros I've come up with but
which I'm not sure about.

My DSL is aimed ad declaratively building GUIs, making a parallel
between the hierarchical representation of the code and the hierarchy
of GUI widgets, like the Lisp HTML-generating DSLs do. For example,

(frame (:title "sample")
  (panel (:layout ...)
     (label (:text "abc"))
     (button (:action (lambda ...)))))

would render a frame with a panel as its only child, and the panel
would contain a label and a button arranged in some kind of layout.

Currently I have adopted a design in which I write a macro for every
widget (of course I have some support macrology that eliminates most
of the boilerplate). Such macros expand into something like

(let ((#:widget (make-button-widget ...args...)))
  (process-special-args)
  (let ((*parent* #:widget))
    ,@body)
  (when (boundp '*parent*)
    (add-child #:widget *parent*))
  #:widget)

i.e. widgets detect whether there's a parent widget they can
automatically add themselves to. This simplifies the language (no
explicit add-child to call, which would make the whole "hierarchy"
point pretty much useless), but can be a bit odd compared with the
usual semantics of Lisp:

(frame (...)
  (let ((x (panel (...))))
     ...))

will still result in a frame with a panel as a child. I could maybe
provide a dont-add macro or a :dont-add keyword argument to suppress
this behaviour.

The alternative would be to have a single macro (with-gui ...code...)
- akin to with-html and the like - that would walk its body, recognize
top-level widget expressions, and process them.

I don't like very much the second approach. First, because I'd have to
use (or write) some kind of code walker, even if limited. Second, and
probably more important, because I'd lose some IDE interaction (e.g.
argument list suggested while typing).

But there's more...
My DSL uses Swing (Java) as the underlying GUI library, for a number
of reasons. I'd like the DSL to be useful both to Lisp programmers who
need an easy, cross-platform GUI, and Java programmers who need a
simple way to use Swing. I've also in mind that I could use the very
same DSL (same syntax) to produce a Java translation of the same GUI.
For this, the second approach (with-gui macro) is more interesting
since if I used per-widget macros I would need them to produce
completely different expansions based on the value of a compile-time
switch.

What do you think, besides the fact that my explanation is a mess ;-)?

Alessio

From: Kenneth Tilton
Subject: Re: Macro design question
Date: 
Message-ID: <49e0d60c$0$22529$607ed4bc@cv.net>
Alessio Stalla wrote:
> Hello, I'd like to have opinions on the design of a DSL I'm working
> on, in particular on a certain use of macros I've come up with but
> which I'm not sure about.
> 
> My DSL is aimed ad declaratively building GUIs, making a parallel
> between the hierarchical representation of the code and the hierarchy
> of GUI widgets, like the Lisp HTML-generating DSLs do. For example,
> 
> (frame (:title "sample")
>   (panel (:layout ...)
>      (label (:text "abc"))
>      (button (:action (lambda ...)))))
> 
> would render a frame with a panel as its only child, and the panel
> would contain a label and a button arranged in some kind of layout.
> 
> Currently I have adopted a design in which I write a macro for every
> widget (of course I have some support macrology that eliminates most
> of the boilerplate). Such macros expand into something like
> 
> (let ((#:widget (make-button-widget ...args...)))
>   (process-special-args)
>   (let ((*parent* #:widget))
>     ,@body)
>   (when (boundp '*parent*)
>     (add-child #:widget *parent*))
>   #:widget)
> 
> i.e. widgets detect whether there's a parent widget they can
> automatically add themselves to. This simplifies the language (no
> explicit add-child to call, which would make the whole "hierarchy"
> point pretty much useless), but can be a bit odd compared with the
> usual semantics of Lisp:
> 
> (frame (...)
>   (let ((x (panel (...))))
>      ...))
> 
> will still result in a frame with a panel as a child. I could maybe
> provide a dont-add macro or a :dont-add keyword argument to suppress
> this behaviour.
> 
> The alternative would be to have a single macro (with-gui ...code...)
> - akin to with-html and the like - that would walk its body, recognize
> top-level widget expressions, and process them.
> 
> I don't like very much the second approach. First, because I'd have to
> use (or write) some kind of code walker, even if limited. Second, and
> probably more important, because I'd lose some IDE interaction (e.g.
> argument list suggested while typing).
> 
> But there's more...
> My DSL uses Swing (Java) as the underlying GUI library, for a number
> of reasons. I'd like the DSL to be useful both to Lisp programmers who
> need an easy, cross-platform GUI, and Java programmers who need a
> simple way to use Swing. I've also in mind that I could use the very
> same DSL (same syntax) to produce a Java translation of the same GUI.
> For this, the second approach (with-gui macro) is more interesting
> since if I used per-widget macros I would need them to produce
> completely different expansions based on the value of a compile-time
> switch.
> 
> What do you think, besides the fact that my explanation is a mess ;-)?
> 

Your plan looks good and standard for this sort of thing.

What is this Java thing you mentioned?

kt
From: Alessio Stalla
Subject: Re: Macro design question
Date: 
Message-ID: <0509d777-1033-4fae-99ea-ffcc2fd5ba6a@n8g2000vbb.googlegroups.com>
On Apr 11, 7:40 pm, Kenneth Tilton <·········@gmail.com> wrote:
> Alessio Stalla wrote:
> > Hello, I'd like to have opinions on the design of a DSL I'm working
> > on, in particular on a certain use of macros I've come up with but
> > which I'm not sure about.
>
> > My DSL is aimed ad declaratively building GUIs, making a parallel
> > between the hierarchical representation of the code and the hierarchy
> > of GUI widgets, like the Lisp HTML-generating DSLs do. For example,
>
> > (frame (:title "sample")
> >   (panel (:layout ...)
> >      (label (:text "abc"))
> >      (button (:action (lambda ...)))))
>
> > would render a frame with a panel as its only child, and the panel
> > would contain a label and a button arranged in some kind of layout.
>
> > Currently I have adopted a design in which I write a macro for every
> > widget (of course I have some support macrology that eliminates most
> > of the boilerplate). Such macros expand into something like
>
> > (let ((#:widget (make-button-widget ...args...)))
> >   (process-special-args)
> >   (let ((*parent* #:widget))
> >     ,@body)
> >   (when (boundp '*parent*)
> >     (add-child #:widget *parent*))
> >   #:widget)
>
> > i.e. widgets detect whether there's a parent widget they can
> > automatically add themselves to. This simplifies the language (no
> > explicit add-child to call, which would make the whole "hierarchy"
> > point pretty much useless), but can be a bit odd compared with the
> > usual semantics of Lisp:
>
> > (frame (...)
> >   (let ((x (panel (...))))
> >      ...))
>
> > will still result in a frame with a panel as a child. I could maybe
> > provide a dont-add macro or a :dont-add keyword argument to suppress
> > this behaviour.
>
> > The alternative would be to have a single macro (with-gui ...code...)
> > - akin to with-html and the like - that would walk its body, recognize
> > top-level widget expressions, and process them.
>
> > I don't like very much the second approach. First, because I'd have to
> > use (or write) some kind of code walker, even if limited. Second, and
> > probably more important, because I'd lose some IDE interaction (e.g.
> > argument list suggested while typing).
>
> > But there's more...
> > My DSL uses Swing (Java) as the underlying GUI library, for a number
> > of reasons. I'd like the DSL to be useful both to Lisp programmers who
> > need an easy, cross-platform GUI, and Java programmers who need a
> > simple way to use Swing. I've also in mind that I could use the very
> > same DSL (same syntax) to produce a Java translation of the same GUI.
> > For this, the second approach (with-gui macro) is more interesting
> > since if I used per-widget macros I would need them to produce
> > completely different expansions based on the value of a compile-time
> > switch.
>
> > What do you think, besides the fact that my explanation is a mess ;-)?
>
> Your plan looks good and standard for this sort of thing.

Ehm, maybe I failed to explain it right... I don't have a single plan
but two choices (dsl as multiple macros vs dsl as single macro that
transforms code), and I don't know which one to choose, since they
both have something that I don't like ;)

> What is this Java thing you mentioned?

Swing? It's the standard Java GUI library. It's cross-platform (well,
it runs on every platform Java runs on), it's quite featureful and
quite customizable. It's not extremely good looking with it's default
look&feel, but it's supposed to be interchangeable (I've never tried
to, though). But, it's a PITA to write Swing code by hand. Using a GUI
editor can eliminate some of the pain, but also ties you to the IDE
and makes complex layouts very difficult to design imho. So a Lispy
DSL could be handy ;)
If you're thinking Cells, well, I've been looking at a Java library
that does data binding (quite limited compared to Cells), and *maybe*
the two could be made to work together. But that's veeery far in the
future...

Ale
From: Kenneth Tilton
Subject: Re: Macro design question
Date: 
Message-ID: <49e145d0$0$27760$607ed4bc@cv.net>
Alessio Stalla wrote:
> On Apr 11, 7:40 pm, Kenneth Tilton <·········@gmail.com> wrote:
>> Alessio Stalla wrote:
>>> Hello, I'd like to have opinions on the design of a DSL I'm working
>>> on, in particular on a certain use of macros I've come up with but
>>> which I'm not sure about.
>>> My DSL is aimed ad declaratively building GUIs, making a parallel
>>> between the hierarchical representation of the code and the hierarchy
>>> of GUI widgets, like the Lisp HTML-generating DSLs do. For example,
>>> (frame (:title "sample")
>>>   (panel (:layout ...)
>>>      (label (:text "abc"))
>>>      (button (:action (lambda ...)))))
>>> would render a frame with a panel as its only child, and the panel
>>> would contain a label and a button arranged in some kind of layout.
>>> Currently I have adopted a design in which I write a macro for every
>>> widget (of course I have some support macrology that eliminates most
>>> of the boilerplate). Such macros expand into something like
>>> (let ((#:widget (make-button-widget ...args...)))
>>>   (process-special-args)
>>>   (let ((*parent* #:widget))
>>>     ,@body)
>>>   (when (boundp '*parent*)
>>>     (add-child #:widget *parent*))
>>>   #:widget)
>>> i.e. widgets detect whether there's a parent widget they can
>>> automatically add themselves to. This simplifies the language (no
>>> explicit add-child to call, which would make the whole "hierarchy"
>>> point pretty much useless), but can be a bit odd compared with the
>>> usual semantics of Lisp:
>>> (frame (...)
>>>   (let ((x (panel (...))))
>>>      ...))
>>> will still result in a frame with a panel as a child. I could maybe
>>> provide a dont-add macro or a :dont-add keyword argument to suppress
>>> this behaviour.
>>> The alternative would be to have a single macro (with-gui ...code...)
>>> - akin to with-html and the like - that would walk its body, recognize
>>> top-level widget expressions, and process them.
>>> I don't like very much the second approach. First, because I'd have to
>>> use (or write) some kind of code walker, even if limited. Second, and
>>> probably more important, because I'd lose some IDE interaction (e.g.
>>> argument list suggested while typing).
>>> But there's more...
>>> My DSL uses Swing (Java) as the underlying GUI library, for a number
>>> of reasons. I'd like the DSL to be useful both to Lisp programmers who
>>> need an easy, cross-platform GUI, and Java programmers who need a
>>> simple way to use Swing. I've also in mind that I could use the very
>>> same DSL (same syntax) to produce a Java translation of the same GUI.
>>> For this, the second approach (with-gui macro) is more interesting
>>> since if I used per-widget macros I would need them to produce
>>> completely different expansions based on the value of a compile-time
>>> switch.
>>> What do you think, besides the fact that my explanation is a mess ;-)?
>> Your plan looks good and standard for this sort of thing.
> 
> Ehm, maybe I failed to explain it right... I don't have a single plan
> but two choices (dsl as multiple macros vs dsl as single macro that
> transforms code), and I don't know which one to choose, since they
> both have something that I don't like ;)

Oh, no. Multiple macros. Only way to go.


> 
>> What is this Java thing you mentioned?
> 
> Swing? It's the standard Java GUI library. 

No, I mean Java. Never heard of it.

kt
From: Alessio Stalla
Subject: Re: Macro design question
Date: 
Message-ID: <92ad400c-cf12-4640-84d0-9302a48d6c2a@z19g2000vbz.googlegroups.com>
On Apr 12, 3:37 am, Kenneth Tilton <·········@gmail.com> wrote:
> Alessio Stalla wrote:
> > On Apr 11, 7:40 pm, Kenneth Tilton <·········@gmail.com> wrote:
> >> Alessio Stalla wrote:
> >>> Hello, I'd like to have opinions on the design of a DSL I'm working
> >>> on, in particular on a certain use of macros I've come up with but
> >>> which I'm not sure about.
> >>> My DSL is aimed ad declaratively building GUIs, making a parallel
> >>> between the hierarchical representation of the code and the hierarchy
> >>> of GUI widgets, like the Lisp HTML-generating DSLs do. For example,
> >>> (frame (:title "sample")
> >>>   (panel (:layout ...)
> >>>      (label (:text "abc"))
> >>>      (button (:action (lambda ...)))))
> >>> would render a frame with a panel as its only child, and the panel
> >>> would contain a label and a button arranged in some kind of layout.
> >>> Currently I have adopted a design in which I write a macro for every
> >>> widget (of course I have some support macrology that eliminates most
> >>> of the boilerplate). Such macros expand into something like
> >>> (let ((#:widget (make-button-widget ...args...)))
> >>>   (process-special-args)
> >>>   (let ((*parent* #:widget))
> >>>     ,@body)
> >>>   (when (boundp '*parent*)
> >>>     (add-child #:widget *parent*))
> >>>   #:widget)
> >>> i.e. widgets detect whether there's a parent widget they can
> >>> automatically add themselves to. This simplifies the language (no
> >>> explicit add-child to call, which would make the whole "hierarchy"
> >>> point pretty much useless), but can be a bit odd compared with the
> >>> usual semantics of Lisp:
> >>> (frame (...)
> >>>   (let ((x (panel (...))))
> >>>      ...))
> >>> will still result in a frame with a panel as a child. I could maybe
> >>> provide a dont-add macro or a :dont-add keyword argument to suppress
> >>> this behaviour.
> >>> The alternative would be to have a single macro (with-gui ...code...)
> >>> - akin to with-html and the like - that would walk its body, recognize
> >>> top-level widget expressions, and process them.
> >>> I don't like very much the second approach. First, because I'd have to
> >>> use (or write) some kind of code walker, even if limited. Second, and
> >>> probably more important, because I'd lose some IDE interaction (e.g.
> >>> argument list suggested while typing).
> >>> But there's more...
> >>> My DSL uses Swing (Java) as the underlying GUI library, for a number
> >>> of reasons. I'd like the DSL to be useful both to Lisp programmers who
> >>> need an easy, cross-platform GUI, and Java programmers who need a
> >>> simple way to use Swing. I've also in mind that I could use the very
> >>> same DSL (same syntax) to produce a Java translation of the same GUI.
> >>> For this, the second approach (with-gui macro) is more interesting
> >>> since if I used per-widget macros I would need them to produce
> >>> completely different expansions based on the value of a compile-time
> >>> switch.
> >>> What do you think, besides the fact that my explanation is a mess ;-)?
> >> Your plan looks good and standard for this sort of thing.
>
> > Ehm, maybe I failed to explain it right... I don't have a single plan
> > but two choices (dsl as multiple macros vs dsl as single macro that
> > transforms code), and I don't know which one to choose, since they
> > both have something that I don't like ;)
>
> Oh, no. Multiple macros. Only way to go.
>
>
>
> >> What is this Java thing you mentioned?
>
> > Swing? It's the standard Java GUI library.
>
> No, I mean Java. Never heard of it.

Oh, that... it's an island in Indonesia. It's famous for its coffee,
among other things. It's also somehow connected with James Gosling,
though I don't precisely remember why...

Ale
From: Frank Buss
Subject: Re: Macro design question
Date: 
Message-ID: <1plufatcq20wl.1ijelo0amtueh.dlg@40tude.net>
Alessio Stalla wrote:

> But, it's a PITA to write Swing code by hand. Using a GUI
> editor can eliminate some of the pain, but also ties you to the IDE
> and makes complex layouts very difficult to design imho. 

Have you tried http://www.jgoodies.com ? It has a nice custom Look&Feel and
makes writing forms in pure Java very easy, more easier than using a GUI
editor and the result looks more uniform for alle forms you use in your
program.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Alessio Stalla
Subject: Re: Macro design question
Date: 
Message-ID: <9732af63-6bf9-4ee1-bae6-46c73ddcc52c@o18g2000vbi.googlegroups.com>
On Apr 12, 9:12 am, Frank Buss <····@frank-buss.de> wrote:
> Alessio Stalla wrote:
> > But, it's a PITA to write Swing code by hand. Using a GUI
> > editor can eliminate some of the pain, but also ties you to the IDE
> > and makes complex layouts very difficult to design imho.
>
> Have you triedhttp://www.jgoodies.com? It has a nice custom Look&Feel and
> makes writing forms in pure Java very easy, more easier than using a GUI
> editor and the result looks more uniform for alle forms you use in your
> program.

Thanks, I'll look into that (I've already used the JGoodies data
binding library and it's quite cool). However, my ultimate goal is
write as less Java as possible...

Ale
From: TJ Atkins
Subject: Re: Macro design question
Date: 
Message-ID: <fe650fc4-909f-4a07-885a-76ac033d22a3@v28g2000vbb.googlegroups.com>
To address one of your original problems (preventing a widget from
adding itself to the hierarchy when you don't want it to) I'd probably
just go with the simple solution you mention - putting in a :dont-add
option or the like.  Without a code-walker it seems difficult to
distinguish programmatically between the environments in which you
want a widget to auto-add itself and the ones where you don't.

~TJ