[HN Gopher] Thoughts on Clojure UI framework
___________________________________________________________________
Thoughts on Clojure UI framework
Author : lycopodiopsida
Score : 179 points
Date : 2021-09-09 13:35 UTC (9 hours ago)
(HTM) web link (tonsky.me)
(TXT) w3m dump (tonsky.me)
| webmobdev wrote:
| While I appreciate the time invested in researching all this, I
| feel this is "reinventing the wheel". Native GUIs almost always
| offer superior performance and already offer everything that the
| developer(s) of a new framework would have to reinvent. Thus, a
| wrapper around native GUIs makes the most sense. (GUI frameworks
| on Linux though does need an improvement or a complete revamp. )
| linguae wrote:
| One question regarding wrappers around native GUIs as someone
| with little experience writing GUI software: how does the
| wrapper handle different UI/UX guidelines? It's one thing to
| wrap a common button class around Win32, AppKit, Qt, and GTK
| buttons. It's another thing to have the application
| simultaneously comply with the UI/UX guidelines for each
| desktop environment.
| webmobdev wrote:
| > how does the wrapper handle different UI/UX guidelines?
|
| Most of it is automatically handled by the native interface
| of the OS when it renders the UI. Some cases have to be dealt
| by the wrapper library developer, and some of it has to be
| done by the developer creating the app using the wrapper
| library.
|
| For example, a _Window_ usually has the default UI elements
| of a Title Bar, the title text, Max-minimize buttons, window
| resize handlers etc. In Windows, this is rendered with the
| max-minimise buttons on the top-right corner, and the title
| left aligned in the title bar (if I remember right). On
| macOS, the same Window will be rendered with the max-minimise
| button on the top-left corner and the title centered in the
| title bar.
|
| When you create a window on MS Windows OS using the Win32 API
| for it - http://www.winprog.org/tutorial/simple_window.html -
| the rendered window will be, _by default_ , according to
| Microsoft UI / UX guidelines. Similarly, when you create a
| window using the cocoa framework on macOS, the window will be
| rendered, by default, according to the UI / UX guidelines of
| Apple - https://github.com/lukakerr/NSWindowStyles .
|
| This highlights how some UI / UX guidelines are baked into
| the native frameworks.
|
| But if the wrapper library developer wants to offer some
| multi-platform custom UI component not available natively,
| they will have to ensure that the component is compliant with
| UI / UX guidelines of the OS they are rendered in.
|
| (If you want to see this in action with an actual wrapper
| library, check out Lazarus IDE - https://www.lazarus-
| ide.org/index.php ... create a _window_ on it on MS Windows,
| Linux or macOS with it GUI designer and compile the code to
| the see the native window it generates.)
|
| Most of the other things described in the article are also
| already available in the native GUI frameworks. It would make
| more sense to extend and enhance what is lacking, rather than
| re-inventing the whole thing again (which, as you noticed,
| can be a pain if you have to conform to different OS
| guidelines).
| [deleted]
| novok wrote:
| In practice wrapper types have been done many times before, and
| failed to make something good.
|
| Rendering everything yourself is actually as performant or
| potentially more performant than a 'native' set because what
| everyone is doing in the end, including native frameworks, is
| rendering on a rectangle using opengl, vulkan or metal.
| webmobdev wrote:
| VCL on Delphi and LCL on Lazarus ( https://www.lazarus-
| ide.org ) are pretty neat and feature rich wrappers.
| brundolf wrote:
| As someone who believes Electron is genuinely the best existing
| option for cross-platform desktop apps (and possibly desktop apps
| in general), I'm excited to see someone trying to make something
| better by _incorporating_ that context and that progress instead
| of ignoring it. The goals and the ideas here sound well-thought-
| out, and not tone-deaf, and I really hope this goes somewhere.
| diskzero wrote:
| One aspect of Electron app, is that typically you can use the
| most of the same code in the browser. Would you expect to see
| the same result from this project; ClojureScript code running
| in the browser and JVM-backed Clojure running on the desktop?
|
| Like you, I am excited to see this approach. There may be a lot
| of negative opionions about Electron, but you can't deny the
| inroads it has made.
| brundolf wrote:
| It seemed like the author hinted at that (and I believe
| Flutter sets a precedent for it), but I have no firsthand
| knowledge of the project
|
| With that said: I got the sense the author is mainly
| interested in targeting high-complexity desktop apps, which
| tend to have less need to be available in both forms
| tomjen3 wrote:
| Now I am curious, why is Electron a better option than putting
| a simple webserver in your code and then open it in the users
| favourite browser? You get the same options in terms of what
| the JS can do, except you aren't limited to Javascript on the
| backend and you don't need to ship the Chrome runtime to a user
| that already has one.
| brundolf wrote:
| A few things:
|
| 1) Packaging/general polish. With the server solution the
| user doesn't get a desktop icon, or a single .app/.exe, etc.
| Their window manager doesn't work with the app the normal
| way. Etc.
|
| 2) Certain other native integrations. An electron app can
| populate the Mac menu bar, it can use native right-click
| menus, it can do rich notifications that aren't constrained
| to the browser's notifications API, it can show a red dot in
| the system dock, etc.
|
| 3) Stability of pinning to a specific Chromium version.
|
| This can work for some things- mostly developer tools where
| users may not care as much about polish and may care more
| about reducing install size. But it's not really a
| replacement.
| cosmotic wrote:
| I thought Swing did an excellent job with native UIs, though it
| did take some care by the developer.
| brundolf wrote:
| It was slightly before my time so I'm not really sure why it
| suddenly died. I can say the author's correct that a
| declarative style has proven to be more productive in the time
| since, but there was a big gap there between the declarative
| shift and when swing died off.
| cosmotic wrote:
| As someone who's worked on both declarative and procedural
| UI, I'd say declarative is harder to work with. It's much
| more difficult to debug. I think the largest benefit of
| declarative is that it largely mitigates unresponsive UI
| code, though that too is pretty easy with a little care.
| brundolf wrote:
| I've worked with both too (only really on the web, fwiw)
| and I have the opposite feelings. It feels like a huge
| waste of my mental energy to manually keep state in sync
| across different parts of the app when that's pretty well a
| solved problem at this point.
| thom wrote:
| I have been enjoying working on a cljfx project recently.
| Extremely fast to get a prototype together, proper multi core
| support for number crunching, whole JVM ecosystem to reach out
| for functionality. Probably not for the faint hearted but it has
| the advantage that it exists today.
| ducktective wrote:
| > Probably not for the faint hearted
|
| Any advantages over Qt or Electron?
| thom wrote:
| For a Clojure programmer, yes. And for my particular use
| cases I'm happy with this over, for example, React Native
| plus ClojureScript because I can bring in JVM libraries and
| have easy threading.
|
| But if I were starting from a completely blank slate or
| building a startup around something (especially consumer
| based) I'd probably make different choices.
| Scarbutt wrote:
| Why use the language with the most horrible startup time for a
| GUI framework though? The core might be C/C++, but users will
| write their app in Clojure. GraalVM also still has big
| limitations.
| didibus wrote:
| The article explained most of it.
|
| 1) Author wants to use Clojure and is funded by a Clojure
| organization.
|
| 2) Author wants write-once/run-anywhere, which the JVM
| provides.
|
| 3) Author wants live interactive development which Clojure can
| provide.
|
| 4) Author wants multi-core support, and fast runtime, which JVM
| provides.
|
| 5) Author wants a declarative data oriented approach, which
| Clojure is good at.
|
| Finally, the author acknowledges they are concerned about
| startup time, but believe their is hope either with GraalVM
| native compilation support, or a custom Clojure runtime.
| nlitened wrote:
| As far as I understand, the core graphics library will be Skia,
| and it's C++. So to some extent, your wish has been granted.
| Scarbutt wrote:
| What wish?
| nlitened wrote:
| I am sorry, I mistakenly assumed that you thought it would
| be better if the new GUI library used some language like
| C++ instead of Clojure.
| brundolf wrote:
| There would still be JVM startup time even if some parts
| of the process delegate to native code. Though the OP
| acknowledges this and still thinks this is the best
| approach (and plans on mitigating the issue as much as
| possible). I'm of a similar mind: desktop apps tend to be
| long-lived and a few tens or even hundreds of
| milliseconds at startup shouldn't really matter.
| zorr wrote:
| JVM startup time is not great but it's not horrible
| either. Especially in the context of desktop apps that
| are often started once and kept running for a long time.
| With some care it is definitely possible to spin up a JVM
| and display an initialized window within 1 or 2 seconds.
| Which is roughly the same time as Gimp or Krita or
| Thunderbird take to startup on my machines.
|
| I even have a few git-style CLI tools that bootstrap a
| JVM on each invocation without using optimized
| graalvm/native images.
| ithrow wrote:
| I guess you are not familiar with Clojure, it adds a lot
| overhead over the overhead of the JVM to startup time.
| letwhile wrote:
| If your estimation of "time to window" is correct,
| clojure seems like a very bad choice for this
| undertaking.
| zerr wrote:
| Qt doesn't wrap the native controls, wxWidgets does.
| cosmotic wrote:
| I think the article is conflating people's acceptance of web apps
| with people's appreciation of web apps. Web apps (or electron
| apps) are always worse than a well-written native counterpart in
| every verifiable UX metric. Let's not kid ourselves: web apps and
| electron apps are developer-experience focused, not user
| centered.
| Zababa wrote:
| > Web apps (or electron apps) are always worse than a well-
| written native counterpart in every verifiable UX metric.
|
| That is true.
|
| > Let's not kid ourselves: web apps and electron apps are
| developer-experience focused, not user centered.
|
| That isn't true. I spend most of my days on Linux. Before web
| and electron apps, the alternatives were not well-written
| native apps. The alternatives were "Use another program". As a
| user, I'm really glad many things are web-centric these days.
| cosmotic wrote:
| I think you're benefiting from the coincidence that
| developers (managers?) chose Electron + 1 code base and void
| of well-written apps due to low market share. Sure, an
| electron app is better than a broken side project. But a
| fully native linux app would handily beat the electron app.
|
| If there were a larger market share, there would be more
| well-written native apps. If devs focused on users, the
| easily-ported mediocre electron app wouldn't exist.
| rochak wrote:
| I would rather have a slow memory hogging app than no app
| at all.
| [deleted]
| Zababa wrote:
| It's not a coincidence, Electron is here because some
| people don't like web apps. Managers chose web apps.
| BackBlast wrote:
| > Let's not kid ourselves: web apps and electron apps are
| developer-experience focused, not user centered.
|
| Developer problems turn into cost and schedule problems. Users
| very much care about cost and availability.
| phyrex wrote:
| I believe that's what the article said too. Where do you see
| him conflating this?
| cosmotic wrote:
| I suppose it might have been what I inferred when the author
| said "Yet it has been a massive success. I think it means our
| industry is craving for a good desktop UI framework."
| tharne wrote:
| This is really cool. It's great to see someone pushing for good
| desktop applications. I'm not an electron hater, but I don't love
| it either, and I'm happy to see new alternatives emerge, in a fun
| language like clojure no less.
| webmobdev wrote:
| Free and open source: https://www.lazarus-ide.org/index.php
|
| Other 30+ cross-platform GUI toolkits / frameworks:
| https://www.slant.co/topics/983/~best-cross-platform-gui-too...
| pgt wrote:
| Go go go Nikita! If there is anyone in the Clojuresphere who
| could pull this off, it is Tonsky.
| Zelphyr wrote:
| "The web started to get more suitable for apps probably since
| Gmail in 2004. It's very convenient, yet still very limited and
| has shortcomings."
|
| Yes. I worked for over a decade to make web apps behave more like
| native apps. I finally realized it was a fruitless endeavor. The
| browser and the web are amazing but, trying to make them behave
| like native apps just doesn't offer the same experience and, in
| most cases, offers a worse experience. All one need as proof are
| all the Electron apps or the Apple Music desktop app.
| flohofwoe wrote:
| And yet Visual Studio Code is doing quite well for a "slow and
| bloaty" Electron app. It starts many times faster, and in many
| areas (not all) also feels snappier than both Xcode and Visual
| Studio (and being an IDE versus "just a text editor" isn't an
| excuse, VSCode can be turned into a full blown IDE with a few
| extensions).
| eyelidlessness wrote:
| I think a more appropriate comparison for VSCode would be
| Nova, which is angling for roughly the same IDE-capable
| editor space. And uses some of the same technologies (LSP,
| TextMate themes) I'm not at my desk so I can't compare at the
| moment, but I remember Nova feeling vastly more responsive
| and quite a bit faster from launch to usable.
|
| And VSCode performance (especially launch) degrades
| significantly once you have several workspaces open at once.
| I've learned to dread upgrade launches because the release
| notes tab amplifies that degraded performance even more
| (which is baffling because that's just one more web thing in
| the same web context right?!).
|
| Don't get me wrong, I love VSCode, and it's worlds better
| than most other Electron apps I have to use. I even went back
| to it from Nova because it better supports my workflow. But
| it is definitely slower than it could be if it were native.
| Scarbutt wrote:
| VSCode is the exception not the rule. It's an exception
| because it has a large engineering team behind it doing
| thousands of micro-optimizations.
| ducktective wrote:
| That is pretty much the definition of _exception_ in this
| space. Also consider the vast number of man-hours MS has put
| into VSCode (+LSP+DA)
| [deleted]
| brundolf wrote:
| What? The Apple Music desktop app is native, built with
| Catalyst (and is awful despite that)
| askonomm wrote:
| Native and yet still sucks. Most catalyst apps suck.
| Zelphyr wrote:
| If I'm wrong I'll stand corrected but, it behaves way too
| much like a web app to not at least be making heavy use of
| WKWebView.
| brundolf wrote:
| What does "behaves too much like a web app" even mean in
| this context?
| jdminhbg wrote:
| If you go to something like the For You screen, you will
| see a pause while the content is loaded remotely. And if
| you hit Command-R, it will reload, like a web page.
|
| I think the other commenters are right that Music.app is
| written as a native macOS app, but it definitely leans
| heavily on web views for content, especially in the
| streaming parts of the app.
| dboreham wrote:
| Perhaps Amazon Music app?
| marcellus23 wrote:
| It is not built with Catalyst. Podcasts is, but Music is not.
| And presumably he's referring to the webview-based parts of
| Apple Music, i.e. the browsing piece of it. The native parts
| of the app (library browsing and management) work very well
| in my experience.
| chrisweekly wrote:
| Brilliant! Love it! Good luck! Keep us posted!
| mosdl wrote:
| Hates on Electron and bloat, but is fine using vdom which also
| adds memory bloat? Seems like a wierd combo.
| [deleted]
| honko wrote:
| I imagine the bloat from a vdom vs the bloat from chromium is
| somewhat different.
| zerr wrote:
| The bloat from the JVM...
| throwaway34241 wrote:
| From "Why not web":
|
| > I think the fundamental problem of the web is that its APIs are
| too high-level.
|
| Frameworks like Flutter (at least one backend) [1] [2] and Gio
| [3] use low-level APIs like WebGL and WebAssembly. That might not
| be the right choice for a web-first framework but seems
| reasonable for apps that would otherwise be desktop-only and need
| low-level access to be compatible with the native version.
|
| It looks like he's using Skia for rendering so the
| WebGL/WebAssembly Skia port that Flutter uses might be a
| particularly good fit.
|
| I assume a Clojure project would use Clojurescript if it had a
| web target, but I'm not familiar enough to know if the
| Clojure/Clojurescript differences [4] pose a big obstacle for
| this sort of UI framework or not.
|
| [1] https://flutter.dev/docs/development/tools/web-renderers
|
| [2] https://skia.org/docs/user/modules/canvaskit/
|
| [3] https://gioui.org/
|
| [4] https://clojurescript.org/about/differences
| solarkraft wrote:
| Interesting that yesterday's submission of this got buried. Let
| me repeat and elaborate because it's somewhat close to my heart.
|
| > I plan to focus on the high-quality desktop instead of finding
| a mediocre middle ground between desktop and mobile.
|
| Oh god damn it. This space is severely under-served. It's only
| filled by Xamarin Forms, React Native (kinda), Flutter and web.
| They all kind of suck for desktop apps.
|
| It doesn't even have to do both well. It just has to be a great
| experience on one platform and an okay one on others. Phone apps
| can be good desktop apps with minimal modification (as Apple
| realizes 5 years after Microsoft almost did) and not many things
| are worse than happening to use one platform and your
| data/functionality just _not being available_ on it.
|
| Stop it, please. Smartphones are computers. They're used for the
| same things and _increasingly so_. Stop pretending they 're
| fundamentally different. They're not.
|
| Guess why the Web is eating everything. It's WORA. And there's
| close to no competition.
| Zababa wrote:
| > Phone apps can be good desktop apps with minimal modification
|
| I don't really agree here. Phones and desktops are very
| different, and have very different UI needs.
|
| > Stop it, please. Smartphones are computers. They're used for
| the same things, even increasingly so. Stop pretending they're
| that fundamentally different.
|
| Navigating with a mouse and keyboard is not the same thing at
| all ad navigating with your fingers on a touchscreen.
| solarkraft wrote:
| The UI features required are different, but like on websites,
| mobile-first works very well. There are some pretty native-
| feeling Catalyst apps on macOS: Voice Memos (has flaws), Jira
| (very native feel), Vectornator (pretty full featured and
| perfectly native feeling Mac app) and even unmodified iOS
| apps (Metatext) that run great, as well as smartphone-styled
| Apps (Telegram) that are great to use.
|
| Sure. Keyboard shortcuts for text. Right click instead of
| long press. More precision. Hoveing. Swiping back on the
| trackpad instead of the screen. There are differences - but
| they're really not that fundamental. Minimal differences.
|
| We can certainly argue about whether mobile first allows an
| app to use the full potential of the desktop. Maybe not. But
| I honestly don't care that much if the alternative is _no
| app_.
| dmitriid wrote:
| Ah yes. Because an app optimized for touch on a tiny screen
| will scale beautifully to work with precise controls via
| keyboard and mouse/trackpad on large and huge screens.
|
| As evidenced by all the professional apps that require
| little to no modifications.
|
| Oh wait...
| Zababa wrote:
| > But I honestly don't care that much if the alternative is
| no app.
|
| I feel the same, however I still find that mobile first app
| are not a great experience on desktop.
| vosper wrote:
| > Navigating with a mouse and keyboard is not the same thing
| at all ad navigating with your fingers on a touchscreen.
|
| I wonder how many computer users are actually using a mouse
| in 2021. I reckon most people use laptops now, which means
| that people are navigating by touch, either with a trackpad
| or a touchscreen (I think lots of window laptops have touch
| screens?)
|
| There's no way to get actual numbers on this.... is there?
| flohofwoe wrote:
| IMHO using a touchpad on a laptop is still much closer to
| using a mouse than using an iPhone or iPad with touch
| input. I think it's mainly because the touchpad is so
| closely integrated with the keyboard. For instance a touch-
| screen MBP (with the touch screen as replacement of the
| touchpad) would destroy this close keyboard/touchpad
| relationship.
| flohofwoe wrote:
| It's just the hardware that's not user-facing which is similar
| between smartphones and computers. But the whole input model is
| fundamentally different. Software must follow and not dictate
| how humans interact with the hardware, and that's fundamentally
| different between smartphones, tablets and computers.
| didibus wrote:
| > Oh god damn it. This space is severely under-served. It's
| only filled by Xamarin Forms, React Native (kinda), Flutter and
| web. They all kind of suck for desktop apps
|
| This might prove the OPs point, that trying to target both
| creates a mediocre middle ground? And could explain why you're
| unsatisfied with approaches that chose to do that.
| meowphius wrote:
| I read somewhere when someone was criticizing Rust for GUI stuff,
| that lack of OO and inheritance can be a real problem. Is that
| also true for Clojure?
| nlitened wrote:
| If I understand correctly, the author talks about pure-data
| approach to building GUI, and that's pretty much the opposite
| of OO and inheritance.
| elias94 wrote:
| Clojure ecosystem really need something similar. The ability to
| not have to deal with Clojuscript and to pack-ship an app with
| desktop UI easily.
|
| With the work you did on Skija we have high hope! Good luck and
| keep us updated
| creamytaco wrote:
| You criticize Electron and then proceed to make pretty much the
| same mistake by using ... JVM. I don't think this is going to fly
| as a better alternative to JavaScript. It's just one evil
| exchanged for another.
|
| And I'll be extremely surprised if you manage to do smooth
| animations at 144Hz in Clojure without killing battery life.
| Zababa wrote:
| > Did I miss something important that should be covered?
|
| Accessibility. Outside of that everything seems reasonable. But I
| don't know much about cross-platforms GUI. I expect someone will
| come and explain that Delphi or something like that already does
| everything the author wants except for the integration with
| Clojure.
|
| I would add that I'm not sure which value Clojure provides here.
| Does the REPL adds anything to the live-reload environment? If
| not, the choice of Clojure seems to be arbitrary.
| amackera wrote:
| The work is funded by a Clojure community group (and a Clojure-
| using company), and Tonsky has written a bunch of awesome other
| Clojure (see DataScript[1]).
|
| So it seems as though the decision to use Clojure was not made
| for technical reasons, but it's not exactly arbitrary.
|
| [1] https://github.com/tonsky/datascript
| jdminhbg wrote:
| > Does the REPL adds anything to the live-reload environment?
|
| Yes, altering state in a running application is vastly more
| productive than save/compile/reload, even if the latter happens
| automatically.
| dwohnitmok wrote:
| live-reload or hot-reload I've seen usually refer to systems
| that preserve state in a running application (so you're not
| reloading from scratch). So your application never actually
| stops running when new code is loaded and you get the same
| sensation that you're editing the application "in-place."
|
| That being said even in that environment having a REPL is
| nice (although not as much of a quantum leap so much as an
| incremental improvement) because you can use code to directly
| poke at your application but is not actually used by your
| application instead of only being able to write code that
| your application actually uses.
| brundolf wrote:
| I've gathered that lispers have a tendency to say "REPL"
| when they mean "hot reloading", which causes confusion in
| discussions like these
| lilactown wrote:
| I think they are very similar, but different enough that
| it makes sense to use different words. Using just the
| word "REPL" doesn't give much insight into the iceberg of
| capabilities that lisps like Clojure, Common Lisp, etc.
| provide. I wrote a long post about some of the
| differences:
| https://news.ycombinator.com/item?id=28475647
|
| Would love a better word or phrase to differentiate from
| e.g. the way people experience a python or haskell REPL.
| jdminhbg wrote:
| I agree that the term "REPL" is poorly chosen, since
| read-eval-print-loop equally applies to a Bash prompt.
| But in this case, it's even more than hot reloading,
| because you are making changes in the running
| application, not just in the saved source code.
|
| With hot reloading, you can change the appearance or
| behavior of a button and see it reflected immediately.
| With a Clojure REPL, you can do that but also load in
| different data, trigger actions, etc.
| brundolf wrote:
| Then it's possible an even broader term is needed, but
| "REPL", to non-lispers' minds in 2021, means narrowly "a
| prompt where you can type code and then hit enter and see
| a result". I think "hot-reloading" would be a
| dramatically more descriptive term even if it isn't
| perfectly descriptive.
| e12e wrote:
| Live patching.
| didibus wrote:
| Yes, I've been saying "live interactive development"
| instead of REPL more recently, and I think it conveys the
| idea much better. Since in Lisps, a REPL means:
|
| > a live integrated inside an application REPL that lets
| you evaluate and hot-swap every single line of code at
| will and on-demand all at runtime without ever needing to
| restart the application, while also being able to inspect
| the runtime state at will
| Guthur wrote:
| We do have a term for it, it's Image based programming.
| The primary means of interacting with said image is quite
| often the REPL, and so the two may have become
| synonymous.
| jdminhbg wrote:
| To me that term also implies that images are the primary
| means of distribution, as in (most) Smalltalks. That
| said, it's still probably a better term than REPL for the
| Clojure experience.
| Zababa wrote:
| Isn't "altering state in a running application" precisely how
| modern live reloading works?
| lilactown wrote:
| Modern hot reloading and how lispy REPLs work are similar
| in many ways, i.e. they allow you to make changes to a
| running application without stopping it, however there are
| differences in their experience and how they accomplish it.
|
| The primary difference in experience is the unit of change
| that you can make with these systems, which is typically
| based on the unit of compilation of the language you're
| using.
|
| For example if you're using a language whose unit of
| compilation is a file, IME you must reload every change in
| the file at once. This has upstream effects to how hot
| reloading is accomplished, because if you're reloading an
| entire file where you've only _actually_ changed one
| function, then your hot reloading system has two options:
|
| 1. It reloads everything in the file, meaning you're
| potentially losing state that could have been preserved
| across the change. This typically leads developers to
| spread definitions across many files in order to be able to
| make more fine grained changes to their running system.
|
| 2. It uses some heuristic to detect whether state should be
| preserved or not, typically via some static analysis. This
| can be opaque to developers working on applications, and
| adds a lot of complexity to the hot reloading system, but
| is probably the best one can do if your unit of compilation
| is a file.
|
| Lisps, on the other hand, typically make the unit of
| compilation a "form", i.e. a well-formed syntax tree like
| (foo (bar baz)). This, combined with some editor tooling,
| means that I can make extremely fine grained changes to the
| system by selectively evaluating forms within a file,
| preserving its state except for the form that was
| evaluated.
|
| The way this works in practice is: I have my editor open
| and connected to my running application using an extension.
| I place my cursor on a form I have changed and use a hot
| key to compile and send that form to the running
| application. I can view the return value of that form in my
| editor, and if there were any side effects (e.g. re-
| defining a variable or function), my application will now
| exhibit that new behavior.
|
| Side note: the benefits of being able to evaluate forms and
| see their output in my editor is hard to state. It turns
| your editor from a one-way communication tool (I make
| changes, hit save, and those changes get made to the
| application) to a bidirectional tool, where I can both
| change and inspect the running system. I wish more
| languages had robust tooling for this.
|
| The other difference that you tend to see between languages
| (even between languages with just hot reloading) is late
| vs. early binding. Lisps are typically very late bound, so
| you don't need to recompile and/or restart your application
| on every change.
|
| Other languages who bind earlier have to deal with stale
| bindings. Even JS hot reloading has to deal with this
| problem in complex ways because most bundlers use closures
| as modules and bind their inter-module dependencies on
| instantiation, which means that even though you in theory
| don't need to recompile or reload anything except the one
| JS function you just changed, in practice you have to
| reload the file and any files that depend on it, which puts
| us back in the position of needing to use some sort of
| static analysis to detect what has actually changed in
| order to precisely invalidate application state.
|
| I hope this mountain of text helps highlight the subtle
| differences between hot reloading and a lisp REPL. It's not
| just the tooling but the specific semantics of the language
| that make a difference when trying to make changes to a
| running system.
|
| Source: my experience working with and developing tools for
| hot reloading and REPL development in JS, ClojureScript and
| Clojure
| zorr wrote:
| This is a great writeup and good to see I'm not the only one
| looking at JVM for cross platform desktop apps.
|
| Recently I've been experimenting with TornadoFX and it is very
| nice to work with. It's a Kotlin wrapper for JavaFX providing a
| "declarative builder DSL" to compose views. It uses a MVVM
| approach where the View components are bound to the ViewModel
| using observables. JavaFX supports CSS for styling components
| including variables without the clunky web css variable syntax.
| And with Kotlin coroutines/suspend functions it's trivial to add
| async IO for network and disk access.
|
| Combine all that with modern JVM and Gradle tooling for native
| packaging (deb/rpm/msi/dmg) and access to the huge ecosystem of
| JVM libraries.
|
| Of course there are drawbacks. JVM startup time isn't great but
| even with Spring Dependency Injection my project starts up in
| under a second which is fine for a long-running desktop app imho.
| It will never be as fast or consume as little memory as a native
| toolkit does but to me it's the pragmatic sweet spot in between
| native toolkits and packaging a full webbrowser like Electron.
|
| I'm not affiliated with TornadoFX or JavaFX, just a happy user
| that has rediscovered joy in building desktop apps again.
___________________________________________________________________
(page generated 2021-09-09 23:00 UTC)