Farfetched blog

View My GitHub Profile

Functional Relational Reactive Programming

15 Dec 2024

You can simply refer to fields on events and reactive objects.

basic reactivity

a = 100
b = a * 2
// b is 200
a = 111
// b is 222 now

compound objects

dan_smith:
    name = "Daniel Smith"
    school = "Something Academy"
    gpa = 4.0

mr_dan_smith:
    dan_smith.with:
        title = "Mr."
        status = 100

functions and immutability

treble(x):
    return x * 3

b = treble(a)

f():
    m = 2
    return x * m

g(x):
    b = 234 //does not compile
    //only the repl can reassign "globals"
    return 234

h():
    a:
        name = "Daniel Smith"
        school = "Something Academy"

    a.school = "Other School" //does not compile
    //objects are immutable

    b = a.with:
        school = "Other School"
    return b

reactive sets

Here’s where we dramatically diverge from FRP. The “a” or “an” prefix defines a reactive set.

a student:
    name = NewStudentMsg.name
    school = NewStudentMsg.school
    gpa = average(CourseCompletedMsg.grade or 0)
student_body:
    size = count(student)
    average_gpa = average(student.gpa)

    //since it's not "student.gpa or 0", there is
    // no student body until there are students,
    // kind of like an sql "inner join"

first class reactivity

a student:
    f(NewStudentMsg).with:
        gpa = average(CourseCompletedMsg.grade or 0)

f(s):
    return:
        name = s.name
        school = s.school

structural typing

x = student + 3
    //does not compile: students don't support "+"

big plans

Everything persists across restarts. Can this be used in place of SQL as well as scripting?

templates

The vibe is friendly to templates, as in HTML templates like JSX. Perhaps we could embed in a document without too much extra syntax or machinery.

boring and TODO

arithmetic, comparisons, loops, conditionals, lists, subobjects, hash tables. all very python inspired, but simpler if possible

nerdier stuff

Functions cannot even read from members of object sets that are not passed as parameters.

We’ll want some optimization in order to be able to support “perl -pie” type use cases.

We’ll want some kind of sum type even with structural types for handling nulls safely.

questions

What is the best use of “:” vs “=”? Next line vs same line? Or function/object vs simple variable? Or just give up “=”?

Do we want functions reading from simple reactive objects? What can we do to make a comfortable language subset for configuration use cases?

Do we want to support variable rebinding? Or can we just have a better support for looping and refining a value, and for chaining steps without intermediate names?

Do IDs need to be visible in the language, or just in the serialization?

How to work with exceptionals and maintain referential transparency?

Replacing SQL (and JQ and XPath) and interactive shell and templates and regexes all want string literals that need not be quoted. Perhaps there should be a mode in each variables are $ prefixed? Or is it worth giving up non-prefixed variables?

Is the syntax too error-prone defining functions without a keyword?

How do we support “schema” evolution?

Would it be beneficial to have structural typing be driven by test object literals? What about generating a protobuf schema from those? What about annotations, or does it make sense to have more first class support for the “schema first” approach? Think about contracts/interfaces and structural typing.

Think about safe “select *” usage and reflection in general.

RSS