Building with Parenscript and Preact: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 7: Line 7:
Damn... I guess I gotta try this out.
Damn... I guess I gotta try this out.


I have a thing for tools that are off the beaten path but are super powerful. I call them "secret weapons" since everyone sees "Lisp" or "Pascal" or whatever and immediately turns their brain off while you're doubling your productivity. I figured it might be fun to put something together with Parenscript to see what the fuss is all about. I saw an article from Holger Sindbaek about how he's making 10k a month off a Solitaire game, so I figured I might try to get in on some of that action; plus I have fond memories as a kid of opening FreeCell and watching the king's head turn left and right to follow the mouse.
I have a thing for tools that are off the beaten path but are super powerful. I call them "secret weapons" since everyone sees "Lisp" or "Pascal" or whatever and immediately turns their brain off while you're doubling your productivity. I figured it might be fun to put something together with Parenscript to see what the fuss is all about. I saw an [https://www.indiehackers.com/post/how-i-grew-a-simple-solitaire-game-to-10k-mrr-28e352c308 article from Holger Sindbaek] about how he's making 10k a month off a Solitaire game, so I figured I might try to get in on some of that action; plus I have fond memories as a kid of opening FreeCell and watching the king's head turn left and right to follow the mouse.


[[File:King2.apng]]
[[File:King2.apng]]
Line 17: Line 17:
Since I want to side-step the modern frontend stack a bit, I found Preact as an alternative implementation of React in 3kb, and it [https://dev.to/jovidecroock/prefresh-fast-refresh-for-preact-26kg has a blog post] describing how to hook into its hot updating system. I quickly whipped up a macro which implements a JSX-like syntax, and a <code>defcomponent</code> macro for creating React components, so I can write something like this:
Since I want to side-step the modern frontend stack a bit, I found Preact as an alternative implementation of React in 3kb, and it [https://dev.to/jovidecroock/prefresh-fast-refresh-for-preact-26kg has a blog post] describing how to hook into its hot updating system. I quickly whipped up a macro which implements a JSX-like syntax, and a <code>defcomponent</code> macro for creating React components, so I can write something like this:


<syntaxhighlight lang="lisp">(defcomponent -ui-button () (props)
<syntaxhighlight lang="lisp">
  (with-defaults (on-click (disabled false) children) props
(defcomponent -counter (((counter set-counter) (use-state 0))) ()
    (psx
  (psx
    (:div ((on-click on-click)
  (:div ()
            (class-name (class-names "ui-button" (when disabled "disabled")))
        "The button has been clicked "
            (style (create "color"
        (:span ((style (create "color" "red")))
                          (if disabled
                (chain counter (to-string)))
                            "grey"
        " times."
                            "black"))))
        (:button ((onclick (lambda () (set-counter (1+ counter)))))
          children))))</syntaxhighlight>
                  "Increment"))))
</syntaxhighlight>
 
[[File:Clicked.png]]


and have it compile into:
and have it compile into:
Line 32: Line 35:
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
var s = $RefreshSig$();
var s = $RefreshSig$();
function UiButton(props) {
function Counter() {
     s();
     s();
     var disabled304 = 'undefined' === typeof props.disabled ? false : props.disabled;
     var _db1107 = preactHooks.useState(0);
    var counter = _db1107[0];
    var setCounter = _db1107[1];
     __PS_MV_REG = [];
     __PS_MV_REG = [];
     return [preact.h('div', Object.assign({ onClick : props.onClick,
     return [preact.h('div', Object.assign({ }), ['The button has been clicked '], [preact.h('span', Object.assign({ style : { 'color' : 'red' } }), [counter.toString()])], [' times.'], [preact.h('button', Object.assign({ onclick : function () {
                                            className : classNames('ui-button', disabled304 ? 'disabled' : null),
        __PS_MV_REG = [];
                                            style : { 'color' : disabled304 ? 'grey' : 'black' }
        return setCounter(counter + 1);
                                          }), [props.children])];
    } }), ['Increment'])])];
};
};
s(UiButton, '', false, function () {
s(Counter, 'useState{[counter, setCounter](0)}', false, function () {
     return [];
     return [];
});
});
$RefreshReg$(UiButton, 'UiButton');
$RefreshReg$(Counter, 'Counter');
flushUpdates();
flushUpdates();
</syntaxhighlight>
</syntaxhighlight>
Line 52: Line 57:
[[File:Lisp-preact.mp4|1000px]]
[[File:Lisp-preact.mp4|1000px]]


And it's true, it only took about 50 lines of macro code to implement. Combine that with trident-mode to push the snippets to the frontend for evaluation, and you have a full fledged interactive hot reloading environment! I don't want to get all Reddit about it, but:
And it's true, it only took about [https://github.com/SuperDisk/cardgames/blob/dbf74fc105fde68cb4962a8b7ff7dcfb231db34f/preact.lisp#L53 50 lines of macro code to implement.] Combine that with trident-mode to push the snippets to the frontend for evaluation, and you have a full fledged interactive hot reloading environment! I don't want to get all Reddit about it, but:


[[File:8q5nqk.jpg]]
[[File:8q5nqk.jpg]]
Line 126: Line 131:


Check out the game here: https://online-freecell.com
Check out the game here: https://online-freecell.com
Source code is all here: https://github.com/SuperDisk/cardgames


By the way, I'm looking for a job, so if you or anyone you know is hiring and needs a really good developer, [mailto:yux50000@hotmail.com please let me know ;)]
By the way, I'm looking for a job, so if you or anyone you know is hiring and needs a really good developer, [mailto:yux50000@hotmail.com please let me know ;)]

Navigation menu