Lisp HUG Maillist Archive

RE: (Actually about Fonts) Using defparameter inside a function to make and bind a list of variables

Sorry I’ve been offline for so many days. But I’m back online now.

 

I’m appreciating the examples, different ways of implementing, and explanations.

 

I’m responding particularly to “…We still don’t know what you want to do? Why do you want to create…”.

 

Here is the story. I have been learning CAPI and Interface Builder. I tried Interface Builder. Interface Builder is good. I tried to change a font.

 

Let me try to reconstruct what I was trying to do in Interface Builder. Here is the code from Interface Builder:

 

=========== Start Code from Interface Builder =================

(capi:define-interface interface-1 ()

  ()

  (:panes

   (title-pane-1

    capi:title-pane

    :text "Title-Pane-1"

    :font (graphics-ports:make-font-description :size 24)))    ; <<< === the font line

  (:layouts

   (column-layout-1

    capi:column-layout

    '(title-pane-1)))

  (:default-initargs

   :best-height 14

   :best-width 130

   :layout 'column-layout-1

   :title "Interface-1"))

=========== End Code from Interface Builder =================

 

See the :font line? I saw this has no effect in Interface Builder. Martin Simons explained to me I could make it work by defining a variable. For example, I could do:

 

========== Start code line ==========

(defparameter *font-for-titles-3*

              (gp:make-font-description :size 24))

========== End code line ==========

 

Then I can use *font-for-titles-3* in Interface Builder. Then the code comes out like this

 

=========== Start Code from Interface Builder =================

(capi:define-interface interface-1 ()

  ()

  (:panes

   (title-pane-1

    capi:title-pane

    :text "Title-Pane-1"

    :font *font-for-titles-3*))    ;  <<<=====  the font line

  (:layouts

   (column-layout-1

    capi:column-layout

    '(title-pane-1)))

  (:default-initargs

   :best-height 39

   :best-width 172

   :layout 'column-layout-1

   :title "Interface-1"))

=========== End Code from Interface Builder =================

 

This indeed works. So now I have control over the fonts in my Graphical User Interface (GUI).

 

I have not tried it yet, but I think my original font definition would work outside of Interface Builder.

 

 

Then, I started to try writing the GUI without Interface Builder. But quickly I saw that that is too hard for me because I need to understand much more what I am doing. Interface Builder lets me see a lot of what is available for buttons, panels, and so forth. Then I can look up details in the CAPI manual. And the Interface Builder generates code that works. I can refer to the CAPI manual to tweak the code inside or outside Interface Builder.

 

I would suppose that one of the main “reasons to be” of Interface Builder is so that people like me can program without having to learn and understand so much. Even though the more I understand the better and quicker I can write programs and get desired results, managers like to see progress on my programs. Learning and understanding take time. Managers like to see progress even in the case where I am The Manager managing myself.

 

What comes out of all this is that my question is really all about fonts because I cannot type  

    (graphics-ports:make-font-description :size 24)))

in Attributes in Interface Builder and see any results (in Interface Builder).

 

I had a thought that I could create all the fonts I might ever use all at once. Maybe I could do defparameter in a recursively called function or a loop. After gaining some more learning and understanding from all of you in Lisp-HUG, I think, maybe better just to write a Lisp function that generates a Lisp code file. concatenate is easy. Streams are easy. Etc. defparameter and defconstant would work because I would be defining at compile-time.

 

Generating all the fonts makes Interface Designer more like a Visual Basic or C# type of GUI designer tool. Then all my pre-defined font variables would be something like

 

     *font-times-10*

     *font-times-12*

     *font-times-18*

     *font-times-24*

     *font-times-10-bold*

     *font-times-12-bold*

     *font-times-18-bold*

     *font-times-24-bold*

     etc.

     *font-ariel-10*

     *font-ariel-12*

     *font-ariel-18*

     *font-ariel-24*

     etc.

     etc.

 

But now I have learned even more from all of you. I think better to think of the fonts NOT the way I would think in Visual Basic, but rather in the way I think when writing HTML and CSS web pages. In CSS I don’t try to define all the fonts I will ever use for the rest of my life! That would be so wasteful in space and time. It’s just too much to include in every GUI program. Thinking more like I would for writing CSS, I would define fonts for each type of thing. So, my Lisp font variable names would be more like

 

     *title-main*

     *title-sub-1*

     *title-sub-2*

     *label-1*

     *label-2*

     *label-config-major*

     *label-config-minor*

     *list-box-regular*

     etc.

 

And then as I design the GUI, I could decide it looks better in Ariel or bolded. I would modify the font variables. Then, the fonts would automatically apply consistently throughout my GUI. Martin mentioned that the font variables facilitate using the same font definition in multiple places in the GUI.

 

In any case, I feel that conversing with all of you has been very beneficial, leading me to see on my own that my early idea of defining all fonts is certainly not what I want to do.

 

I’m not finished listening. If my words stimulate some thoughts, I’m listening and learning from the more experienced Lispers.

 

 

Ron Lewis

 

 

 

From: tfb@tfeb.org <tfb@tfeb.org>
Sent: Saturday, May 19, 2018 12:46 PM
To: Pascal Bourguignon <pjb@informatimago.com>
Cc: Ron Lewis <rlewis-4d@indinfer.com>; Lisp HUG <lisp-hug@lispworks.com>
Subject: Re: Using defparameter inside a function to make and bind a list of variables

 

On 18 May 2018, at 18:55, Pascal Bourguignon <pjb@informatimago.com> wrote:

 

Once you start using eval-when to do things at compilation time, you should consider writing a macro instead!

 

yes, and in fact if I was doing this I'd do just that -- have a make-* function and a define-* macro which expanded into a suitable (eval-when (...) (make-* ....))

 

We still don’t know what you want to do? Why do you want to create global variables at run-time, that cannot possibly be referenced (for lack of a time machine) by the code that is already compiled?

 

Just to be clear I'm not the original referent of 'you' here.  It is the sort of thing people used to do a lot of but I'd certainly find other ways of doing the same thing I think  -- if I needed some kind of dynamically-defined dynamically-scoped object I'd write some syntax for that and not use specials (or, probably I would use some internal special in the implementation but not at the user level).

 

--tim

Re: (Actually about Fonts) Using defparameter inside a function to make and bind a list of variables

If you need to generate them in advance, you can use a macro. In Lisp the need to output and compile/load code files is very rare (unless you're writing a compiler or loader, that is).

On 23 May 2018 at 01:53, Ron Lewis <rlewis-4d@indinfer.com> wrote:

Sorry I’ve been offline for so many days. But I’m back online now.

 

I’m appreciating the examples, different ways of implementing, and explanations.

 

I’m responding particularly to “…We still don’t know what you want to do? Why do you want to create…”.

 

Here is the story. I have been learning CAPI and Interface Builder. I tried Interface Builder. Interface Builder is good. I tried to change a font.

 

Let me try to reconstruct what I was trying to do in Interface Builder. Here is the code from Interface Builder:

 

=========== Start Code from Interface Builder =================

(capi:define-interface interface-1 ()

  ()

  (:panes

   (title-pane-1

    capi:title-pane

    :text "Title-Pane-1"

    :font (graphics-ports:make-font-description :size 24)))    ; <<< === the font line

  (:layouts

   (column-layout-1

    capi:column-layout

    '(title-pane-1)))

  (:default-initargs

   :best-height 14

   :best-width 130

   :layout 'column-layout-1

   :title "Interface-1"))

=========== End Code from Interface Builder =================

 

See the :font line? I saw this has no effect in Interface Builder. Martin Simons explained to me I could make it work by defining a variable. For example, I could do:

 

========== Start code line ==========

(defparameter *font-for-titles-3*

              (gp:make-font-description :size 24))

========== End code line ==========

 

Then I can use *font-for-titles-3* in Interface Builder. Then the code comes out like this

 

=========== Start Code from Interface Builder =================

(capi:define-interface interface-1 ()

  ()

  (:panes

   (title-pane-1

    capi:title-pane

    :text "Title-Pane-1"

    :font *font-for-titles-3*))    ;  <<<=====  the font line

  (:layouts

   (column-layout-1

    capi:column-layout

    '(title-pane-1)))

  (:default-initargs

   :best-height 39

   :best-width 172

   :layout 'column-layout-1

   :title "Interface-1"))

=========== End Code from Interface Builder =================

 

This indeed works. So now I have control over the fonts in my Graphical User Interface (GUI).

 

I have not tried it yet, but I think my original font definition would work outside of Interface Builder.

 

 

Then, I started to try writing the GUI without Interface Builder. But quickly I saw that that is too hard for me because I need to understand much more what I am doing. Interface Builder lets me see a lot of what is available for buttons, panels, and so forth. Then I can look up details in the CAPI manual. And the Interface Builder generates code that works. I can refer to the CAPI manual to tweak the code inside or outside Interface Builder.

 

I would suppose that one of the main “reasons to be” of Interface Builder is so that people like me can program without having to learn and understand so much.. Even though the more I understand the better and quicker I can write programs and get desired results, managers like to see progress on my programs. Learning and understanding take time. Managers like to see progress even in the case where I am The Manager managing myself.

 

What comes out of all this is that my question is really all about fonts because I cannot type  

    (graphics-ports:make-font-description :size 24)))

in Attributes in Interface Builder and see any results (in Interface Builder).

 

I had a thought that I could create all the fonts I might ever use all at once. Maybe I could do defparameter in a recursively called function or a loop. After gaining some more learning and understanding from all of you in Lisp-HUG, I think, maybe better just to write a Lisp function that generates a Lisp code file. concatenate is easy. Streams are easy. Etc. defparameter and defconstant would work because I would be defining at compile-time.

 

Generating all the fonts makes Interface Designer more like a Visual Basic or C# type of GUI designer tool. Then all my pre-defined font variables would be something like

 

     *font-times-10*

     *font-times-12*

     *font-times-18*

     *font-times-24*

     *font-times-10-bold*

     *font-times-12-bold*

     *font-times-18-bold*

     *font-times-24-bold*

     etc.

     *font-ariel-10*

     *font-ariel-12*

     *font-ariel-18*

     *font-ariel-24*

     etc.

     etc.

 

But now I have learned even more from all of you. I think better to think of the fonts NOT the way I would think in Visual Basic, but rather in the way I think when writing HTML and CSS web pages. In CSS I don’t try to define all the fonts I will ever use for the rest of my life! That would be so wasteful in space and time. It’s just too much to include in every GUI program. Thinking more like I would for writing CSS, I would define fonts for each type of thing. So, my Lisp font variable names would be more like

 

     *title-main*

     *title-sub-1*

     *title-sub-2*

     *label-1*

     *label-2*

     *label-config-major*

     *label-config-minor*

     *list-box-regular*

     etc.

 

And then as I design the GUI, I could decide it looks better in Ariel or bolded. I would modify the font variables. Then, the fonts would automatically apply consistently throughout my GUI. Martin mentioned that the font variables facilitate using the same font definition in multiple places in the GUI.

 

In any case, I feel that conversing with all of you has been very beneficial, leading me to see on my own that my early idea of defining all fonts is certainly not what I want to do.

 

I’m not finished listening. If my words stimulate some thoughts, I’m listening and learning from the more experienced Lispers.

 

 

Ron Lewis

 

 

 

From: tfb@tfeb.org <tfb@tfeb.org>
Sent: Saturday, May 19, 2018 12:46 PM
To: Pascal Bourguignon <pjb@informatimago.com>
Cc: Ron Lewis <rlewis-4d@indinfer.com>; Lisp HUG <lisp-hug@lispworks.com>
Subject: Re: Using defparameter inside a function to make and bind a list of variables

 

On 18 May 2018, at 18:55, Pascal Bourguignon <pjb@informatimago.com> wrote:

 

Once you start using eval-when to do things at compilation time, you should consider writing a macro instead!

 

yes, and in fact if I was doing this I'd do just that -- have a make-* function and a define-* macro which expanded into a suitable (eval-when (...) (make-* ...))

 

We still don’t know what you want to do? Why do you want to create global variables at run-time, that cannot possibly be referenced (for lack of a time machine) by the code that is already compiled?

 

Just to be clear I'm not the original referent of 'you' here.  It is the sort of thing people used to do a lot of but I'd certainly find other ways of doing the same thing I think  -- if I needed some kind of dynamically-defined dynamically-scoped object I'd write some syntax for that and not use specials (or, probably I would use some internal special in the implementation but not at the user level).

 

--tim


Re: (Actually about Fonts) Using defparameter inside a function to make and bind a list of variables

Hi,

Unfortunately Interface Bulder is not available on OSX so if you want to
build UIs there you would have to learn CAPI manually :(

"Ron Lewis" <rlewis-4d@indinfer.com> writes:

> Sorry I’ve been offline for so many days. But I’m back online
> now.
>
> I’m appreciating the examples, different ways of implementing,
> and explanations.
>
> I’m responding particularly to “…We still don’t know what you
> want to do? Why do you want to create…”.
>
> Here is the story. I have been learning CAPI and Interface
> Builder. I tried Interface Builder. Interface Builder is good. I tried
> to change a font. 
>
> Let me try to reconstruct what I was trying to do in Interface
> Builder. Here is the code from Interface Builder:
>
> =========== Start Code from Interface Builder
> =================
>
> (capi:define-interface interface-1 ()
>
> ()
>
> (:panes
>
> (title-pane-1
>
> capi:title-pane
>
> :text "Title-Pane-1"
>
> :font (graphics-ports:make-font-description :size 24))) ; <<<
> === the font line
>
> (:layouts
>
> (column-layout-1
>
> capi:column-layout
>
> '(title-pane-1)))
>
> (:default-initargs
>
> :best-height 14
>
> :best-width 130
>
> :layout 'column-layout-1
>
> :title "Interface-1"))
>
> =========== End Code from Interface Builder
> =================
>
> See the :font line? I saw this has no effect in Interface Builder.
> Martin Simons explained to me I could make it work by defining a
> variable. For example, I could do:
>
> ========== Start code line ==========
>
> (defparameter *font-for-titles-3*
>
> (gp:make-font-description :size 24))
>
> ========== End code line ==========
>
> Then I can use *font-for-titles-3* in Interface Builder. Then the
> code comes out like this
>
> =========== Start Code from Interface Builder
> =================
>
> (capi:define-interface interface-1 ()
>
> ()
>
> (:panes
>
> (title-pane-1
>
> capi:title-pane
>
> :text "Title-Pane-1"
>
> :font *font-for-titles-3*)) ; <<<===== the font line
>
> (:layouts
>
> (column-layout-1
>
> capi:column-layout
>
> '(title-pane-1)))
>
> (:default-initargs
>
> :best-height 39
>
> :best-width 172
>
> :layout 'column-layout-1
>
> :title "Interface-1"))
>
> =========== End Code from Interface Builder
> =================
>
> This indeed works. So now I have control over the fonts in my
> Graphical User Interface (GUI). 
>
> I have not tried it yet, but I think my original font definition
> would work outside of Interface Builder.
>
> Then, I started to try writing the GUI without Interface Builder.
> But quickly I saw that that is too hard for me because I need to
> understand much more what I am doing. Interface Builder lets
> me see a lot of what is available for buttons, panels, and so
> forth. Then I can look up details in the CAPI manual. And the
> Interface Builder generates code that works. I can refer to the
> CAPI manual to tweak the code inside or outside Interface
> Builder.
>
> I would suppose that one of the main “reasons to be” of Interface
> Builder is so that people like me can program without having to
> learn and understand so much. Even though the more I
> understand the better and quicker I can write programs and get
> desired results, managers like to see progress on my programs.
> Learning and understanding take time. Managers like to see
> progress even in the case where I am The Manager managing
> myself.
>
> What comes out of all this is that my question is really all about
> fonts because I cannot type 
>
> (graphics-ports:make-font-description :size 24)))
>
> in Attributes in Interface Builder and see any results (in Interface
> Builder).
>
> I had a thought that I could create all the fonts I might ever use
> all at once. Maybe I could do defparameter in a recursively called
> function or a loop. After gaining some more learning and
> understanding from all of you in Lisp-HUG, I think, maybe better
> just to write a Lisp function that generates a Lisp code file.
> concatenate is easy. Streams are easy. Etc. defparameter and
> defconstant would work because I would be defining at
> compile-time.
>
> Generating all the fonts makes Interface Designer more like a
> Visual Basic or C# type of GUI designer tool. Then all my
> pre-defined font variables would be something like
>
> *font-times-10*
>
> *font-times-12*
>
> *font-times-18*
>
> *font-times-24*
>
> *font-times-10-bold*
>
> *font-times-12-bold*
>
> *font-times-18-bold*
>
> *font-times-24-bold*
>
> etc.
>
> *font-ariel-10*
>
> *font-ariel-12*
>
> *font-ariel-18*
>
> *font-ariel-24*
>
> etc.
>
> etc.
>
> But now I have learned even more from all of you. I think better
> to think of the fonts NOT the way I would think in Visual Basic,
> but rather in the way I think when writing HTML and CSS web
> pages. In CSS I don’t try to define all the fonts I will ever use for
> the rest of my life! That would be so wasteful in space and time.
> It’s just too much to include in every GUI program. Thinking
> more like I would for writing CSS, I would define fonts for each
> type of thing. So, my Lisp font variable names would be more like
>
> *title-main*
>
> *title-sub-1*
>
> *title-sub-2*
>
> *label-1*
>
> *label-2*
>
> *label-config-major*
>
> *label-config-minor*
>
> *list-box-regular*
>
> etc.
>
> And then as I design the GUI, I could decide it looks better in
> Ariel or bolded. I would modify the font variables. Then, the fonts
> would automatically apply consistently throughout my GUI.
> Martin mentioned that the font variables facilitate using the
> same font definition in multiple places in the GUI.
>
> In any case, I feel that conversing with all of you has been very
> beneficial, leading me to see on my own that my early idea of
> defining all fonts is certainly not what I want to do. 
>
> I’m not finished listening. If my words stimulate some thoughts,
> I’m listening and learning from the more experienced Lispers.
>
> Ron Lewis
>
> From: tfb@tfeb.org <tfb@tfeb.org> 
> Sent: Saturday, May 19, 2018 12:46 PM
> To: Pascal Bourguignon <pjb@informatimago.com>
> Cc: Ron Lewis <rlewis-4d@indinfer.com> Lisp HUG
> <lisp-hug@lispworks.com>
> Subject: Re: Using defparameter inside a function to make and
> bind a list of variables
>
> On 18 May 2018, at 18:55, Pascal Bourguignon
> <pjb@informatimago.com> wrote:
>
>  Once you start using eval-when to do things at compilation
>  time, you should consider writing a macro instead!
>
> yes, and in fact if I was doing this I'd do just that -- have a
> make-* function and a define-* macro which expanded into a
> suitable (eval-when (...) (make-* ...))
>
>  We still don’t know what you want to do? Why do you
>  want to create global variables at run-time, that cannot
>  possibly be referenced (for lack of a time machine) by the
>  code that is already compiled?
>
> Just to be clear I'm not the original referent of 'you' here. It is the
> sort of thing people used to do a lot of but I'd certainly find other
> ways of doing the same thing I think -- if I needed some kind of
> dynamically-defined dynamically-scoped object I'd write some
> syntax for that and not use specials (or, probably I would use
> some internal special in the implementation but not at the user
> level).
>
> --tim
>
>

-- 
Br,
/Alexey

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: (Actually about Fonts) Using defparameter inside a function to make and bind a list of variables

I also don't have interface-builder (I'm another Mac person).  I can confirm that your version with the explicit make-font-description call in the initarg works fine as a program.

It seems to me that what you probably want to be able to do is to create a bunch of global variables whose values are font descriptions of various kinds.  But the number of variables, and their names, is fixed at compile-time: you don't actually need to be able to generate them dynamically at runtime.

So, this is an ideal task for a special-purpose macro which just expands into what you need.  Here is one which is probably not right (and may be buggy):

(defmacro define-fonts ((&key (prefix 'font)
                              (suffix nil))
                        &body font-descriptions)
  ;; define a bunch of variables containing font descriptions.  This
  ;; is only useful at the top level
  (labels ((stringify (x)
             ;; turn X into a string, trying to deal with symbols in a
             ;; case-safe way.
             (typecase x
               (symbol (symbol-name x))
               (t (format nil "~A" x))))
           (make-font-name (description)
             ;; Make a symbol name for a font description.  I think
             ;; font-descriptions are property lists / lists of
             ;; keyword arguments, and I also hope that everything in
             ;; them is printable.  If this is not true then this
             ;; needs to be changed.  You might also want to change
             ;; this if you just want the names to look different.
             (intern (format nil "*~@[~A-~]~{~A-~A~^-~}~@[-~A~]*"
                             (and prefix (stringify prefix))
                             (mapcar #'stringify description)
                             (and suffix (stringify suffix)))
                     *package*)))
    `(progn
       ,@(loop for fd in font-descriptions
               for name = (make-font-name fd)
               collect
               `(defparameter ,name (gp:make-font-description ,@fd))))))

You would use this, at the top level in a file (or just interactively) like this:

(define-fonts ()
  (:size 24)
  (:size 12))

And this expands into

(progn
  (defparameter *font-size-24* (graphics-ports:make-font-description :size 24))
  (defparameter *font-size-12* (graphics-ports:make-font-description :size 12)))

You can also customise the variable names a little if you like:

(define-fonts (:prefix my-font
               :suffix description)
  (:size 24)
  (:size 12))

Expands into

(progn
  (defparameter *my-font-size-24-description* (graphics-ports:make-font-description
                                               :size 24))
  (defparameter *my-font-size-12-description* (graphics-ports:make-font-description
                                               :size 12)))

Note you can obviously provide multiple attributes per font:

(define-fonts ()
  (:size 24 :bold t))

expands to

(progn
  (defparameter *font-size-24-bold-t* (graphics-ports:make-font-description :size 24
                                       :bold t)))

--tim


> On 23 May 2018, at 00:53, Ron Lewis <rlewis-4d@indinfer.com> wrote:
> 
> Sorry I’ve been offline for so many days. But I’m back online now.
>  
> I’m appreciating the examples, different ways of implementing, and explanations.
>  
> I’m responding particularly to “…We still don’t know what you want to do? Why do you want to create…”.
>  
> Here is the story. I have been learning CAPI and Interface Builder. I tried Interface Builder. Interface Builder is good. I tried to change a font. 
>  
> Let me try to reconstruct what I was trying to do in Interface Builder. Here is the code from Interface Builder:
>  
> =========== Start Code from Interface Builder =================
> (capi:define-interface interface-1 ()
>   ()
>   (:panes
>    (title-pane-1
>     capi:title-pane
>     :text "Title-Pane-1"
>     :font (graphics-ports:make-font-description :size 24)))    ; <<< === the font line
>   (:layouts
>    (column-layout-1
>     capi:column-layout
>     '(title-pane-1)))
>   (:default-initargs
>    :best-height 14
>    :best-width 130
>    :layout 'column-layout-1
>    :title "Interface-1"))
> =========== End Code from Interface Builder =================
>  
> See the :font line? I saw this has no effect in Interface Builder. Martin Simons explained to me I could make it work by defining a variable. For example, I could do:
>  
> ========== Start code line ==========
> (defparameter *font-for-titles-3*
>               (gp:make-font-description :size 24))
> ========== End code line ==========
>  
> Then I can use *font-for-titles-3* in Interface Builder. Then the code comes out like this
>  
> =========== Start Code from Interface Builder =================
> (capi:define-interface interface-1 ()
>   ()
>   (:panes
>    (title-pane-1
>     capi:title-pane
>     :text "Title-Pane-1"
>     :font *font-for-titles-3*))    ;  <<<=====  the font line
>   (:layouts
>    (column-layout-1
>     capi:column-layout
>     '(title-pane-1)))
>   (:default-initargs
>    :best-height 39
>    :best-width 172
>    :layout 'column-layout-1
>    :title "Interface-1"))
> =========== End Code from Interface Builder =================
>  
> This indeed works. So now I have control over the fonts in my Graphical User Interface (GUI). 
>  
> I have not tried it yet, but I think my original font definition would work outside of Interface Builder.
>  
>  
> Then, I started to try writing the GUI without Interface Builder. But quickly I saw that that is too hard for me because I need to understand much more what I am doing. Interface Builder lets me see a lot of what is available for buttons, panels, and so forth. Then I can look up details in the CAPI manual. And the Interface Builder generates code that works. I can refer to the CAPI manual to tweak the code inside or outside Interface Builder.
>  
> I would suppose that one of the main “reasons to be” of Interface Builder is so that people like me can program without having to learn and understand so much. Even though the more I understand the better and quicker I can write programs and get desired results, managers like to see progress on my programs. Learning and understanding take time. Managers like to see progress even in the case where I am The Manager managing myself.
>  
> What comes out of all this is that my question is really all about fonts because I cannot type  
>     (graphics-ports:make-font-description :size 24)))
> in Attributes in Interface Builder and see any results (in Interface Builder).
>  
> I had a thought that I could create all the fonts I might ever use all at once. Maybe I could do defparameter in a recursively called function or a loop. After gaining some more learning and understanding from all of you in Lisp-HUG, I think, maybe better just to write a Lisp function that generates a Lisp code file. concatenate is easy. Streams are easy. Etc. defparameter and defconstant would work because I would be defining at compile-time.
>  
> Generating all the fonts makes Interface Designer more like a Visual Basic or C# type of GUI designer tool. Then all my pre-defined font variables would be something like
>  
>      *font-times-10*
>      *font-times-12*
>      *font-times-18*
>      *font-times-24*
>      *font-times-10-bold*
>      *font-times-12-bold*
>      *font-times-18-bold*
>      *font-times-24-bold*
>      etc.
>      *font-ariel-10*
>      *font-ariel-12*
>      *font-ariel-18*
>      *font-ariel-24*
>      etc.
>      etc.
>  
> But now I have learned even more from all of you. I think better to think of the fonts NOT the way I would think in Visual Basic, but rather in the way I think when writing HTML and CSS web pages. In CSS I don’t try to define all the fonts I will ever use for the rest of my life! That would be so wasteful in space and time. It’s just too much to include in every GUI program. Thinking more like I would for writing CSS, I would define fonts for each type of thing. So, my Lisp font variable names would be more like
>  
>      *title-main*
>      *title-sub-1*
>      *title-sub-2*
>      *label-1*
>      *label-2*
>      *label-config-major*
>      *label-config-minor*
>      *list-box-regular*
>      etc.
>  
> And then as I design the GUI, I could decide it looks better in Ariel or bolded. I would modify the font variables. Then, the fonts would automatically apply consistently throughout my GUI. Martin mentioned that the font variables facilitate using the same font definition in multiple places in the GUI.
>  
> In any case, I feel that conversing with all of you has been very beneficial, leading me to see on my own that my early idea of defining all fonts is certainly not what I want to do. 
>  
> I’m not finished listening. If my words stimulate some thoughts, I’m listening and learning from the more experienced Lispers.
>  
>  
> Ron Lewis
>  
>  
>  
> From: tfb@tfeb.org <tfb@tfeb.org> 
> Sent: Saturday, May 19, 2018 12:46 PM
> To: Pascal Bourguignon <pjb@informatimago.com>
> Cc: Ron Lewis <rlewis-4d@indinfer.com> Lisp HUG <lisp-hug@lispworks.com>
> Subject: Re: Using defparameter inside a function to make and bind a list of variables
>  
> On 18 May 2018, at 18:55, Pascal Bourguignon <pjb@informatimago.com> wrote:
>>  
>> Once you start using eval-when to do things at compilation time, you should consider writing a macro instead!
>  
> yes, and in fact if I was doing this I'd do just that -- have a make-* function and a define-* macro which expanded into a suitable (eval-when (...) (make-* ...))
> 
>>  
>> We still don’t know what you want to do? Why do you want to create global variables at run-time, that cannot possibly be referenced (for lack of a time machine) by the code that is already compiled?
>  
> Just to be clear I'm not the original referent of 'you' here.  It is the sort of thing people used to do a lot of but I'd certainly find other ways of doing the same thing I think  -- if I needed some kind of dynamically-defined dynamically-scoped object I'd write some syntax for that and not use specials (or, probably I would use some internal special in the implementation but not at the user level).
>  
> --tim


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: (Actually about Fonts) Using defparameter inside a function to make and bind a list of variables

And FWIW here is a fancier version of the same thing which lets you say, for instance

(define-fonts ()
 (:size 24)
 (*foo* :size 12))

Which expands to 

(progn
  (defparameter *font-size-24* (graphics-ports:make-font-description :size 24))
  (defparameter *foo* (graphics-ports:make-font-description :size 12)))

I don't really use CAPI so I am not sure if any of this is the right approach.

(defmacro define-fonts ((&key (prefix 'font)
                             (suffix nil))
                       &body font-descriptions)
 ;; define a bunch of variables containing font descriptions.  This
 ;; is only useful at the top level
 (labels ((parse-fd (fd)
            ;; a font description is either (name .. avs) or avs.  The
            ;; way of telling if the first element is a name is that
            ;; it's a symbol and not a keyword while the second
            ;; element *is* a keyword.  This returns two values: the
            ;; name (either given or derived below) and the avs.  The
            ;; avs are not carefully checked.
            (unless (and (consp fd) (not (null (rest fd))))
              (error "~A can't be an fd"))
            (if (and (symbolp (first fd)) (not (keywordp (first fd)))
                     (keywordp (second fd)))
                (values (first fd) (rest fd))
              (values (make-font-name fd) fd)))
          (make-font-name (description)
            ;; Make a symbol name for a font description.  I think
            ;; font-descriptions are property lists / lists of
            ;; keyword arguments, and I also hope that everything in
            ;; them is printable.  If this is not true then this
            ;; needs to be changed.  You might also want to change
            ;; this if you just want the names to look different.
            (intern (format nil "*~@[~A-~]~{~A-~A~^-~}~@[-~A~]*"
                            (and prefix (stringify prefix))
                            (mapcar #'stringify description)
                            (and suffix (stringify suffix)))
                    *package*))
          (stringify (x)
            ;; turn X into a string, trying to deal with symbols in a
            ;; case-safe way.
            (typecase x
              (symbol (symbol-name x))
              (t (format nil "~A" x)))))

Updated at: 2020-12-10 08:29 UTC