🍦

VanJSのF#ブリッジ:VanFSをリリースした

2024/05/01に公開

VanJS公式サイトで、Community Add-onsとしてリストされています。

image


https://github.com/ken-okabe/vanfs

🍦 VanFS: 1:1 bindings from F# to VanJS (an ultra-lightweight , zero-dependency , and unopinionated Reactive UI framework based on pure vanilla JavaScript and DOM without React/JSX) + WebComponents + FRP

Contents
🍦 VanFS
🚀 Getting Started
🌐 Web Components
⚡️ Functional Reactive Programming (FRP)
⏱️ Timeline
⏱️ Nullable Types
⏱️ Timeline Nullable
⏱️ Timeline Task
⏱️ Timeline Task Concat
⏱️ Timeline Task Or
⏱️ Timeline Task And
💬 Discussions
vanfs

🍦 VanFS

image

VanFS is a project template for 1:1 bindings from F# to VanJS (A tiny Reactive UI Framework without React/JSX) + WebComponents + FRP (Functional reactive programming)

What is VanJS?

image

https://github.com/vanjs-org/van

🍦 VanJS: World's smallest reactive UI framework. Incredibly Powerful, Insanely Small - Everyone can build a useful UI app in an hour.

https://vanjs.org

VanJS (abbreviated Vanilla JavaScript) is an ultra-lightweight , zero-dependency , and unopinionated Reactive UI framework based on pure vanilla JavaScript and DOM. Programming with VanJS feels like building React apps in a scripting language, without JSX. Check-out the Hello World code below:

VanJS code in JavaScript

import van from "vanjs-core"

const { a, p, div, li, ul } = van.tags
// Reusable components can be just pure vanilla JavaScript functions.
// Here we capitalize the first letter to follow React conventions.
const Hello =
    () =>
        div(
            p("👋Hello"),
            ul(
                li("🗺️World"),
                li(a({ href: "https://vanjs.org/" }, "🍦VanJS")),
            ),
        )

van.add(document.body, Hello())

Try on jsfiddle

VanFS is a F# project template for one-to-one direct bindings of VanJS

VanFS code in F#

module HelloApp
open Browser
open Browser.Types
open Fable.Core.JsInterop
open Van.Basic // import tags, add

let a: Tag = tags?a
let p: Tag = tags?p
let div: Tag = tags?div
let ul: Tag = tags?ul
let li: Tag = tags?li

let Hello =
    fun _ ->
        div [
            p ["👋Hello"]
            ul [
                li ["🗺️World"]
                li [a [{|href="https://vanjs.org/"|}; "🍦VanJS"]]
            ]
        ]

add [document.body; Hello()]
|> ignore

Demo

https://codepen.io/kentechgeek/pen/VwNOVOx

image

Why VanJS is based on Vanilla JavaScript

VanJS: About - the Story behind VanJS

But I think, in a nutshell, the best way to describe it is: VanJS is the scripting language for UI, just like bash is the scripting language for terminal.

Being the scripting language for UI , is the fundamental principle that guides the design of VanJS . It's based on JavaScript so that it can work in as many environments as possibles, not only for websites, but also for webviews which most major OSes support.

VanJS: About - How Did VanJS Get Its Name?

Under the hood, VanJS stays truthful to Vanilla JavaScript as close as possible, as there is no transpiling, virtual DOM or any hidden logic. VanJS code can be translated to Vanilla JavaScript code in a very straightforward way.

Why we should avoid using JavaScript

VanJS is a library based on Vanilla JavaScript for the well-established reasons.

However, to take full advantage of VanJS , we should consider using alternative languages instead of JavaScript , which are commonly referred to as AltJS .

One of the critical reasons is that JavaScript is not a type-safe language , which can lead to runtime errors and bugs.

The Effect of Programming Language On Software Quality

An Experiment About Static and Dynamic Type Systems Doubts About the Positive Impact of Static Type Systems on Development Time

Most notably, it does appear that strong typing is modestly better than weak typing, and among functional languages, static typing is also somewhat better than dynamic typing. We also find that functional languages are somewhat better than procedural languages. It is worth noting that these modest effects arising from language design are overwhelmingly dominated by the process factors such as project size, team size, and commit size. However, we hasten to caution the reader that even these modest effects might quite possibly be due to other, intangible process factors, e.g., the preference of certain personality types for functional, static and strongly typed languages.

In fact, in modern web development, JavaScript has increasingly become a compile target from other languages, such as TypeScript.

image

TypeScript -> JavaScript

VanJS can be regarded as a compile target from VanFS (AltJS)

VanFS (AltJS) -> VanJS

image

Why we should avoid using TypeScript and migrate to F#

image

F# gives you simplicity and succinctness like Python with correctness , robustness and performance beyond C# or Java.

Undoubtedly, TypeScript is the most commonly used AltJS. It is a superset of JavaScript that adds type safety and other features. So why not use TypeScript?

There are many reasons, but chief among them is developer productivity .

For instance, the below are the identical code written in TypeScript and F#.

let bindT = <A, B>
    (monadf: (a: A) => Timeline<B>) =>
    (timelineA: Timeline<A>): Timeline<B> => {
        let timelineB = monadf(timelineA.lastVal);
        let newFn = (a: A) => {
            nextT(monadf(a).lastVal)(timelineB);
            return undefined;
        };
        timelineA.lastFns = timelineA.lastFns.concat([newFn]);
        return timelineB;
    };

In TypeScript, compared with legacy JavaScript, an additional step is required to add type signatures to all variables, functions, and parameters. This is often overwhelming.

let bindT =
    fun monadf timelineA ->
        let timelineB = timelineA.lastVal |> monadf
        let newFn =
            fun a ->
                timelineB
                |> nextT (a |> monadf).lastVal
                |> ignore
        timelineA.lastFns <- timelineA.lastFns @ [ newFn ]
        timelineB

The F# code is much cleaner and more readable than TypeScript code.

In F#, we rarely need to add types manually thanks to its powerful type inference. This makes F# development feel similar to legacy JavaScript coding.

In reality, it is much more than that.

image

The powerful F# compiler automatically generates type annotations in VSCode editor, eliminating the need for manual typing that TypeScript demands.

image

While programmers may want to define fundamental object types that form the backbone of their code, in other places, if the F# compiler warns for a demand of manual type annotations, usually, something is wrong .

In F#, if the compiler cannot infer the type, it often suggests that there may be mathematical inconsistencies.

In TypeScript, if the compiler cannot infer the type, it often suggests limitations in its type inference capabilities. This makes it hard to determine the precise cause of the problem.

As a result, F# programmers are naturally led to write mathematically consistent and rigorous code; unfortunately, this benefit rarely happens in TypeScript.

image

F# as an AltJS: A Comparison with TypeScript

F# is generally recognized as running on the .NET Framework, but just as TypeScript is compiled to JavaScript, F# is also compiled to JavaScript.

  • TypeScript -> JavaScript

  • F# -> JavaScript

More precisely,

TypeScirpt
TypeScript Compiler running on Node.js (npx tsc)
JavaScript running in the browser

F#
Fable Compiler running on .NET (dotnet fable)
JavaScript running in the browser

Therefore, the backbone of VanFS is Fable.

image

Fable enables F# code to be compiled to JavaScript and run in the browser.

Why browser? Why VanJS?

There are a lot of Why s here!

I've created a separate article on this topic since it's part of the larger frontend app development landscape and deserves a focused discussion with my own opinions.

📱 Versatility of Web Technology for Cross-Platform App Development

image

続きは

https://github.com/ken-okabe/vanfs

Discussion