Hey folks! Right now I explore an idea about bring...
# linking-together
t
Hey folks! Right now I explore an idea about bringing some of the ideas of Functional Relational Programming (“Out of the tar pit” paper, here is a quick summary) to the mainstream development. I have a problem and thought maybe somebody could help me here 🙂 In my app, I have two variables in state and they are somewhat connected: one can be changed programmatically and another one is changed by the underlying system when an event happens. If one of them changed, another one should be changed too to stay in sync. Right now each variable has its own place, its own change callback and basically there are 2 places where code should be written. What I want to do is to create some kind of “relation” between those two in a declarative manner and store it (or just have in code). So, when one of the variables changes, other changes too automatically and in one place. And also, it’ll be nice to create an ability to subscribe to the relation (and not particular variable), maybe put some constrains on it, etc. But I’m struggling with creating that “Relation” entity. What it should be? An object? A function? How can I create a declarative way for creating relations? Does somebody have ideas or thoughts? Thanks in advance! P.S. I do UI development mainly (swift, kotlin, iOS, Andoid), but feel free to elaborate in any language or system, I think I could adapt 😉
c
This sounds like Rx observables
So, if you were building a product detail page, which shows the quantity left in stock, and the price of adding the selected quantity, you could set up a relationship like the following:
Copy code
$quantityInStock = subscribeToItemQuantity(itemId)
$currentPrice = subscribeToItemPrice(itemId)
$quantitySelected = ReactiveValue(1)
Copy code
// shown in UI view
$validSelected = minOfLatest($quantitySelected, $quantityInStock) 

$totalCostOfSelection = combineLatest($currentPrice, $validSelected).pipe(map(([price, selected]) => multiplyMoney(price, selected))
$displayTotalCostOfSelection = $totalCostOfSelection.pipe(map(formatMoneyFn))
I believe the Swift community has been promoting parts of this pattern with the name Model-View View-Model (MVVM).
t
Yeah, Rx is the way definitely, i’ll try that, thanks! Also, maybe I’ll find something in clojure’s atom, its also an interesting concept.
c
I have a few write-ups which talk about MVVM in a way which completely separates the "View" from the "Business logic". I've given a couple talks about it, and you can find some of the content here https://refactorordie.com/#todo-app-sample https://github.com/RefactorOrDie/refactorordie.com/blob/master/storybook/stories/writing/presentations/ObservableStateOct2019/TodoApp/src/app/TodoState.js It's in JS/React built on top of RxJS, but the concepts work well for many languages
t
Thanks! I’ll do!
e
You didn't make the question clear enough to give an answer. In Physics you have independent variables, like an XYZ coordinate, and they are somewhat connected in that the object that possesses those coordinates might be redrawn on the screen. So the screen re-render becomes a process that is activated by some mechanism when the X, Y, or Z (any of the 3) changes. And if you have other objects flying around, then collision detection must be performed. And maybe if the XYZ is past a boundary, then something has to happen; a sound effect or a deformation of the shape to prevent moving past a point, or it bounces. In interactive graphics you have perhaps 100 things on the screen, and depending on state changes, regeneration of some widget or visualization of the model has to change. If you are talking about a derived quantity, it is an entirely different thing, and in a spreadsheet you have automatic natural order of recomputation, so that if B = A * 2, when A changes B is updated automatically. Under the hood of every spreadsheet is a topological sort of the dependencies of each formula, and of course this means circularity can be detected and the user warned. So if your variables have a single direction dependency, then the spreadsheet works well. TK/Sover, which was Visicalc's sequel product, introduced bidirectional formula modification, so that if you changed B in the above formula it would then fix A based on the mutual constraint. Once you have multiple variables and complicated formulae TK/Solver got a bit gnarly, and so few people are doing reverse modeling the product is long forgotten. It was actually a far more clever product than Visicalc. In the model/view world you have the model generating visualizations, which are dependent on the model variables for how they are drawn, then the rendered visualizations are interacted with, and user clicks/gestures feed back into the model, which then triggers the re-render of the visualization to track the input. When this happens at 60 frames per second, the user doesn't realize how much work is being done. Anyway it would be helpful if you gave a very specific example. The are only 6 permutations of 3 things, and 8 combinations of 3 things, so that is only 14 ways to think about 3 things. A concrete example would clarify which of the scenarios you are trying to encode. A subscription to a relation between A and B creates a third thing C which is watching.
d
The Cell programming language is a very interesting take on functional relational programming. I think there's a difference between expressing functional/relational logic in a high level declarative language, as you can do in Cell, vs encoding that logic in a lower level language like Javascript + Rx using shared mutable state and callbacks. http://cell-lang.net
e
Cell is kind of odd beast. It has some elements of Neo4J, in that it promotes using directed graphs instead of OOP (which is a superior way to do things IMHO). It wasn't clear whether he was building a whole new language or trying to augment existing ones.
t
Thanks @Doug Moen, this is very interesting, haven’t heard about Cell. It has a lot of information on the site, seems exactly what I needed.
@Edward de Jong / Beads Project I don’t have more concrete question because I’m in the position of thinking and researching 🙂 As mentioned, I seek a way to reduce amount of code and accidental complexity in my day-to-day work. One path is to try relational programming and see if its gonna reduce amount of code and increase ability to understand a system. Now I’m looking how to implement “relational ideas” in code and just see what happens. And it seems The Cell Programming Language done exactly this, so I’m gonna inspect it 😄
s
e
The Hirschfeld article uses the example of a dual temperature control UI, where one has both degF and degC on the screen at the same time; any change to one causes the other to be updated. They talk in the paper about "push" and "pull" approaches. They did not however imagine that the underlying runtime would solve this problem for them, and allow a single temperature value to exist in the program. See the Beads dual thermometer example code to see how easy this problem becomes when the language has embedded in the runtime the concept of dependency checking. https://github.com/magicmouse/beads-examples/tree/master/Example%20-temperature The amount of code related to tracking which thing should thing be drawn is considerable in many graphical interactive products. The Cell programming language has an interesting approach to finite state machines, but doesn't address drawing, which is more than 60% of all the code in a graphical interactive product.