Live data from Hacker News

Application-as-a-Function Thinking

doridori.github.io

61–70 of 80 posts

Re: Application-as-a-Function Thinking

#61
post #56
post #29

Very cool to see this! I've actually given this some thought a few years back when attempting to create (yet another) JS framework, and came up with something very similar to this! For me the difficult part was where the side effects fit in and how they're processed, what you call "commands" and "command handler". I didn't find an elegant solution to this and abandoned the idea early on, sparing the JS community.

Great thanks. > For me the difficult part was where the side effects fit in and how they're processed, what you call "commands" and "command handler" Do you mean difficult for you when designing, or difficult to understand in my post?

I meant for me, but also in the article I felt like there should be a bit more on that.

Re: Application-as-a-Function Thinking

#62
post #4

This is basically introducing Elm (a.k.a the inspiration for Redux) to Android. At least for me this model doesn’t work. Application is all about transitions of state, yes, but in context . That’s why React’s model of managing multiple state points in different levels of the application tree makes so much more sense to me

"in context", what does this mean?

Not GP but I can try to explain. React tries to be as functional as possible, but components are still often stateful. For example, an accordian component [1] could have a `collapsed` boolean state. This `collapsed` state makes sense within the context of the accordian component.

Now imagine if you tried to move the state out of all your components into a single location, so that your components can be stateless functions. Now that your variables are out of context and might collide with each other, you might need to rename this `collapsed` state into something like `landingPageItem4AccordianCollapsed`. This is why you shouldn't use global state (like Redux) for everything, and it's often best to keep state close to the UI component it belongs to. This keeps things grouped by context, and makes it easier to navigate and reason about the code.

[1]: https://getbootstrap.com/docs/5.0/components/accordion/

Re: Application-as-a-Function Thinking

#63
post #60
post #21

How well does this approach scale for systems where the state is inherently large and complex? I write code that controls industrial machinery. There's just loads of different knobs and settings and modes that I can control with code, and a single production or test run will involve several heterogeneous machines, so the total state space is the cartesian product of all of those (not to mention the state of the physi…

Hey, I can't say I have ever worked on such a project, it sounds like an interesting problem space. I am assuming when a user interacts with one control button / dial / interaction it has a cascade effect on other controls / displays etc? I am also assuming you already need to have a data structure representing the complete state of the system no? There are multiple interesting aspects here, like are you / do you nee…

>I am assuming when a user interacts with one control button / dial / interaction it has a cascade effect on other controls / displays etc?

Sometimes yes, it depends on the instrument. Some have user interaction, but most don't and are just controlled by the software I write. When I said "knobs" I didn't mean literal knobs, just all the different things these gizmos can do .. they come with thousand-page manuals.

OTOH sometimes shit breaks and you have to go in and send commands manually over telnet to unfuck it, or to gracefully shut down the operation without some delicate and expensive piece of equipment getting torn to pieces.

>I am also assuming you already need to have a data structure representing the complete state of the system no?

Nope, it's only feasible to keep track of the most salient variables. The code is very imperative: machine_a.do_this(), machine_b.do_that(), etc, sometimes for hundreds of lines. So the state changes in the background but it's not legible to us. The machines themselves probably have some representation of their own state in their firmware, but there isn't a single omniscient data structure for the whole system.

>There are multiple interesting aspects here, like are you / do you need to utilise complex state machines here? Just the subject of imperative vs functional state-machines is interesting and a small part of the wider approach.

Yeah we use finite state machines to organize our code, but it's very coarse grained. Stuff like: LoadingState, ArmatureIsMovingState, TakingMeasurementState, etc. Each state in itself will issue many different commands to different machines. It isn't really formally defined where the boundaries are, it's just an informal way to orient ourselves so we can draw a flowchart and not lose our minds from the complexity, and so that there's some way of comparing similar-but-different programs (e.g. a run that measures current and a run that measures Young's modulus will both go in a TakingMeasurementState, but obviously the commands sent will be different).

It's not very amenable to automated unit testing ... I'm not sure what that would even mean in this context. The correct behavior you're testing against would just be ... a sequence of commands to the machines. Which is what the code does already. A unit test would be tautological.

>Another interesting area is it depends on the language and execution environment you are operating in and how expensive operations over immutable data structures are.

We're using Python. I know that pyresistent exists, but honestly we could probably get away with doing naive deepcopies for every single operation and it wouldn't matter for performance. The runtime is completely dominated by the latency of waiting for the machines to do physical stuff (no concurrency for the machine-controller code thankfully; we're not insane). Immutable data structures don't really matter if we can't write down the entire state in the first place.

----

I guess the problem is that pretty much everything interesting that the code does is a side-effect. There are a few things here and there that can be factored out to pure functions and tested, but the overwhelming bulk is the "imperative shell". It's like one of those planets where the core has cooled and the crust has frozen down to comprise most of the total mass.

Re: Application-as-a-Function Thinking

#64

No. Applications are not functions. How many applications that you use on a daily basis work as follows: 1. You prepare some parameters 2. You start the application with those parameters. 3. The application goes away and thinks for a bit. 4. The application returns with a result and then exits. Trying to make actual applications and system fit into the function (or procedure) mold is, IMHO, one of the biggest obstacl…

> How many applications that you use on a daily basis work as follows... Most of them, but then I use the CLI a lot. E.g.: find | grep | xargs foo Where "foo" is (of course) a kind of meta-parameter, both a parameter itself and a function/application. - - - - How do you mean, ALGOL isn't a general purpose language?

1. The shell is not calling functions, it is composing filters via I/O. Superficially similar, but actually quite different. (And how it makes it superficially look like function application is also quite interesting, IMHO).

2. But yes, programs that act like functions definitely do exist. They even used to be in the majority.

3. ALGOL stands for ALGOrithmic Language. It's a DSL for the domain of algorithms. As are virtually all our mainstream so-called "general purpose" languages.

Re: Application-as-a-Function Thinking

#65
post #47

Earlier quoted context omitted.

TFA: Fundamentally an application can be written to have at it’s core, a single, stateless pure function, behold!

Yes, "at its core" being the center of the post. Are you ready to read it now?

You might want to read up on the concept of Architectural Mismatch.

https://repository.upenn.edu/library_papers/68/

https://rd.springer.com/content/pdf/10.1007/978-3-540-92698-...

Re: Application-as-a-Function Thinking

#67
post #51
post #48

Earlier quoted context omitted.

> just a function that takes in the internal state (including the db contents) as an input No Rails (or other) app has a function like this where the entire contents of the DB are passed in as a parameter. And you can't handwave complex internal state as simply another parameter to a function because that complex state can change. That makes the function no longer solely dependent on the parameters passed in. Its beh…

Maybe I've been spending too much time with the state monad, but that still sounds like a function to me. The fact that the DB contents get passed in implicitly as part of the context of a Rails app does not change that.

There's a difference between a "function" that uses implicit contextual state and one that doesn't. We can call it a function with implicit context or we can call it an object or a service or a process. It doesn't really matter as long as we have some way of talking about it. Those other words have been in common use for a long time so it's probably more convenient to use them.

Re: Application-as-a-Function Thinking

#68

Earlier quoted context omitted.

"in context", what does this mean?

Not GP but I can try to explain. React tries to be as functional as possible, but components are still often stateful. For example, an accordian component [1] could have a `collapsed` boolean state. This `collapsed` state makes sense within the context of the accordian component. Now imagine if you tried to move the state out of all your components into a single location, so that your components can be stateless func…

I don't think that's right. I think you'd have a global state like landingPage.Items[].Accordion, and the accordion code in any location would be passed its state and messages already unwrapped by the parent. Nobody would need to know about its collapsed field or any other state it tracks for that matter

Re: Application-as-a-Function Thinking

#69
Love this, thanks for sharing. This is fundamentally how our iOS application is modeled. We were highly inspired by Bernhardt’s talk and the Elm Architecture.

It has lead to a very modular and maintainable app that has been very easy to test without ridiculous mocking you usually see when needing to interact with object-oriented / imperative frameworks like Cocoa Touch.

Re: Application-as-a-Function Thinking

#70

Earlier quoted context omitted.

Not GP but I can try to explain. React tries to be as functional as possible, but components are still often stateful. For example, an accordian component [1] could have a `collapsed` boolean state. This `collapsed` state makes sense within the context of the accordian component. Now imagine if you tried to move the state out of all your components into a single location, so that your components can be stateless func…

I don't think that's right. I think you'd have a global state like landingPage.Items[].Accordion, and the accordion code in any location would be passed its state and messages already unwrapped by the parent. Nobody would need to know about its collapsed field or any other state it tracks for that matter

> I don't think that's right. I think you'd have a global state like landingPage.Items[].Accordion

Somebody correct me if I'm wrong, but I believe this is what React is already doing under the hood when you use useState(). React probably has some big internal global state, and then maintains mappings between state and components, so that when a component is re-rendered, React can pull up the corresponding state for that component.

So even though the components are technically stateless, they can still be considered "stateful" because each component has a corresponding portion in this global state. Notice how in your landingPage.Items[].Accordion, if you change the layout of your landing page, you might now have to change the structure of your global state as well. So this is why React's syntax for keeping the state definitions inside the component is so nice. It prevents you from trying to keep the structure of your global state and the layout of your components in sync.

P.S. I like your work on torrents :P I knew I recognized that username from somewhere

Post reply on HN