Fork me on GitHub
#matrix
<
2023-06-23
>
kennytilton20:06:27

Fun stuff on the Flutter/MX beast, trying to reduce the macro code gen by replacing macros with functions. I have no idea if that ^^^ is an issue, but I am seeing other benefits so soldiering on. Not yet on main , if that tells you anything! So without macros, the Text widget converts to text thus:

(defn _text [fx-props mx-props kids]
  (fxf/make-fx (new fxf/FXDartWidget)
    fx-props
    (assoc mx-props
      :fx-class 'm/Text
      :kids kids
      :fx-gen (fn [me ctx]
                (fxf/ctx-check 'm/Text me ctx)
                (Function.apply
                  m/Text.new
                  [(fx-render ctx
                     (tiltontec.flutter-mx.core/fx-resolve me ctx
                       (first (tiltontec.matrix.api/mkids me))))]
                  (fx-props-resolved me ctx fx-props))))))
Thx to @benjcarmichael for showing me Function.apply and how to use it. 🙏 So why the underscore in _text? Pure U/X, so we do not have to endlessly wrap childen in cFkids. So instead of:
(center
  (column {:mainAxisAlignment m.MainAxisAlignment/center}
    (text {:style (p/TextStyle .color m.Colors/black
                    .fontSize 18.0)}
      "You clicked (+) so many times:")
    (sized-box {:height 14.0})
    (text
      {:style (in-my-context [me ctx]
                (.-headline4 (.-textTheme (m.Theme/of ctx))))}
      {:name  :z-counter
       :value (cI 0)}
      (str (mx/my-value)))))
We write, abbreviating cFkids to cK to minimize the noise:
(cK (center
   (cK (column {:mainAxisAlignment m.MainAxisAlignment/center}
      (cK (text {:style (p/TextStyle .color m.Colors/black
                                .fontSize 18.0)}
                  "You clicked (+) so many times:")
             (sized-box {:height 14.0})
             (text
               {:style (in-my-context [me ctx]
                          (.-headline4 (.-textTheme (m.Theme/of ctx))))}
               {:name  :z-counter
                 :value (cI 0)}
               (cK (str (mx/my-value)))))))))
So close, yet so far. But how does the underscore help? A much simpler deftag generates the text macro that wraps children automagically:
(deftag-ex text tiltontec.flutter-mx.core/_text)
As for the hairier function _text, that is temporary. Note that it is 90% generic, so the internals can be expressed by a small family of widget makers:
(defn _text [fx-props mx-props kids]
  (fxf/make-fx (new fxf/FXDartWidget)
    fx-props
    (assoc mx-props
      :fx-class 'm/Text
      :kids kids
      :fx-gen (fn [me ctx]
                (fxf/ctx-check 'm/Text me ctx)
                (Function.apply m/Text.new
                  [(fx-render ctx
                     (tiltontec.flutter-mx.core/fx-resolve me ctx
                       (first (tiltontec.matrix.api/mkids me))))]
                  (fx-props-resolved me ctx fx-props))))))
So then we would have:
(deftag-ex text tiltontec.flutter-mx.core/_text konly-param-stateless)
Almost back where we started! But if users end up writing deftags for new Flutter classes, it might be easier on them. But what if we end up writing a utility that scrapes their doc or uses dart:mirror to scan the whole class hierarchy and autogen the current macros? Then I would need to understand whether the macro expansions were really a problem, or if other benefits accrue from lightening the macrology. Maintainability? Testing? :thinking_face:

2