Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement a network resource #28

Open
purpleidea opened this issue May 5, 2016 · 13 comments
Open

implement a network resource #28

purpleidea opened this issue May 5, 2016 · 13 comments

Comments

@purpleidea
Copy link
Owner

Managing a network interface is a fundamental part of managing any system. We should provide a native interface to do so. Some ideas:

  • It might be worth basing this on systemd-networkd. (It looks like a safe, stable base!)
  • Since mgmt works in a decentralized manner, so transient network "blips" shouldn't disrupt it.
  • During CheckApply() if we don't transition to an acceptable state, we could revert and error.
  • With the powerful Resource (Res) API, other resources will be able to add automatic edges to this network resource in case they require connectivity. Yet another reason this is an important primitive to write.
  • I'd focus on getting simple networking working initially, with support for bridges or other systemd-networkd features as an exciting second step.

Patches welcome! Please feel free to make yourself known if you'd like to work on this

@purpleidea purpleidea changed the title create a network resource implement a network resource May 5, 2016
@mikefaille
Copy link
Contributor

mikefaille commented Sep 18, 2016

Maybe, we can simply build plugin system as Docker's plugins or Ansible module. The goal is to provide way to implement many solutions.

At least, we can enforce common api for all systems. And, network management solutions can exist in many ways like :

@purpleidea
Copy link
Owner Author

@mikefaille I don't think we need a plugin system, at least not until we have more core base resources.

systemd-networkd

Indeed this is mentioned in the original description.

systems without network manager activated for one specific interface

Does this code support the interfaces to generating events when something changes? I expect it will be best to wrap networkd for now.

These issue tickets are open to attract someone to want to work on the code. Since you're commenting, are you volunteering? :)

@LrsK
Copy link
Contributor

LrsK commented Dec 8, 2016

As I was prodded by @purpleidea, I'm taking a stab at this! So far these are my thoughts on how the resource should work.

The resource controls the systemd-networkd configuration, which takes place via configuration files that are placed in the directory /etc/systemd/network. Networks are configured in files with extension ".network", and virtual network devices are configured in files with extension ".netdev". So the mgmt resource will describe and enforce one or more network configurations. Each configuration ends up in a file e.g. /etc/systemd/network/10-static_ip.network

Configuration files are sorted and processed in lexical order by the networkd service on startup. The first file that has a [Match] field that matches one of its devices among all the config files is used, even if a later file matches as well, so priority matters. The resource should let the user describe the configuration with all the same options that exist in networkd, where several validations will have to take place, like IP adresses, CIDRs, MAC addresses, as well as some conditional cases. Finally the service will have to be restarted for the changes to take effect.

This will result in one or more config files, but some files may already exist on the system. Question then is what should happen to the existing config? Should all existing files be deleted, and replaced by new ones defined by the user? What if something goes wrong in the new config? You could lose contact with the machine. Perhaps a backup can be taken first, and roll back somehow upon some test failing.

@purpleidea
Copy link
Owner Author

@LrsK Hey, feel free to join #mgmtconfig on Freenode IRC if you'd prefer a more back and forth conversation, also ghangouts are possible. Here are a few replies:

  1. Only devices which we decide to manage get managed. Everything else should be ignored. If the user tries to do a badly planned mixed management approach, then it's really their fault.

  2. Rollback is something I'm especially excited about. One of the goals of mgmt being distributed is that the net resource could have a sort of health check function where if the new config didn't satisfy this check (and it can't find it's peers anymore) we can rollback to the old config and generate an error. I've got more ideas here if you'd like to talk more.

  3. We can use the existing file resource code to make this work as a composite resource, so no need to rewrite all of it.

  4. We might need to get netlink events somehow to know when an interface changes.

LMK if you have more questions!

@LrsK
Copy link
Contributor

LrsK commented Dec 9, 2016

Something else I was thinking about was that networkd isn't used that much yet, at least not in some of the distros I've tested on like Ubuntu 16.04, Fedora 24, CentOS. It is indeed possible to use networkd on these systems, but they don't seem to use them by default.

Would it be a good idea to allow the user to specify what format they would like to output the config files in, and place them in the appropriate place on the system? We could solve this by taking in the set options from the yaml file like normal, and then use text/template to produce the actual files. This way, mgmt can even be used on systems without systemd like Alpine or Gentoo.

This would of course be a bigger job in total, but perhaps we should implement networkd support with this flexibility in mind?

@mikefaille
Copy link
Contributor

mikefaille commented Dec 9, 2016

Personally, I don't recommend to bind stuff on least use tech only for coolnest. To use networkd, you must prepare your OS to transfert network configuration (including pre/post script).

@purpleidea
Copy link
Owner Author

@LrsK I think it is a good idea to support networkd initially because it is IMO the most promising future for server networking. If down the road something else turns out to be more useful, we can always implement that as a second resource.

@mikefaille
Copy link
Contributor

mikefaille commented Jun 23, 2017

@purpleidea I personnally prefer agnostic solution like Tenus. I tried it in the past : https://github.com/mikefaille/docker-group-daemonizer/blob/master/main.go

@snikaein
Copy link

for interface address change events we can use net/route package wait until for sysRTM_NEWADDR & sysRTM_DELADDR message trigger

@purpleidea
Copy link
Owner Author

@sadegh-nikaein Want to either write the base resource or a small proof of concept standalone mainloop showing the events happening?

@snikaein
Copy link

@purpleidea i try that is not work as i expected .
what about this idea etcd package netutil
https://github.com/coreos/etcd/blob/master/pkg/netutil/routes_linux.go
has a function call GetDefaultHost return the first IP address of machine from the routing table
we can store it somewhere and check it with some interval or
we can on init add bridge to that with Tenus and not matter interface change or not
or maybe mix of both !?

@purpleidea
Copy link
Owner Author

@sadegh-nikaein Getting/Setting on the interface is the easy part, the less straight forward part is getting events, eg from NETLINK. In any case it should be a straight forward exercise for someone wanting to do the patching. LMK if you're interested.

@snikaein
Copy link

snikaein commented Jun 25, 2017

purpleidea pushed a commit that referenced this issue Apr 25, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 7, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 7, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 12, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 15, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 17, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 23, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue May 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jun 29, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jun 29, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jun 29, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jun 30, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jul 3, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jul 15, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jul 19, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jul 27, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Jul 30, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 8, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 9, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 9, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 13, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 20, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 21, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 22, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 22, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 27, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 28, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 29, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 30, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Aug 31, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 4, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 4, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 19, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 19, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 19, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
purpleidea pushed a commit that referenced this issue Sep 19, 2023
This is the 1st commit message:

lang: Split FuncValue into FuncValue and SimpleFn

Representing an MCL function value as a golang function from Value to
Value was a mistake, it should be a function from Vertex to Vertex.

Here is why this is a mistake:

    The output of a function like

        $f = fn(x) {
          Shell(Sprintf("seq %d", x))
        }

    varies over time, while a single Value does not. Thus, code like

        Map($f, list(1, 2))

    would first produce the value list("1", "1"), but then it would
    _not_ update to list("1", "2") when "seq 2" produces its second
    line. That's because with the mistaken design, when Map receives a
    new FuncValue or a new input list of N elements, Map calls the
    function from Value to Value N times and produces a single output
    list of N elements.

Here is why the corrected design is better:

    Here's what happens with this new design when Map receives a new
    FuncValue or a new input list of N elements.

    First, Map constructs N item-input nodes, each of which extracts a
    different entry from the list. Then, Map calls the function from
    Vertex to Vertex N times, once for each item-input node, and thus
    obtain N item-output nodes. Finally, Map constructs an
    item-collecting node which constructs a list out of all of its
    inputs, and Map connects the N item-output nodes to the
    item-collecting node. This item-collecting node is the output of
    Map.

    The Vertex to Vertex function constructs and connects its own nodes;
    in this case, it constructs an Sprintf node and connects the
    item-input node to it, and then constructs a Shell node and connects
    the Sprintf node to it, and then returns the Shell node as the
    item-output node.

    The two Shell node in this sub-graph emit a first value "1", which
    propagates to the item-collecting node and causes it to output a
    first value list("1", "1"). Then, the second Shell node emits a
    second value "2", which propagates to the item-collecting node and
    causes it to output a second value list("1", "2"), as desired.

Here is how this commit brings us closer to the above plan:

    Changing FuncValue throughout the codebase is a big change. One of
    the difficulties is that it is not just nodes which are emitting
    FuncValues, there are also many other places in the code where
    FuncValue is used to hold a golang function from Value to Value.
    Some of those places now need to hold a golang function from Vertex
    to Vertex, but other places still need to hold a golang function
    from Vertex to Vertex.

    Thus, as a first step, we need to split FuncValue into two types.
    This commit splits the old FuncValue into two types:

    1. The new FuncValue will hold a function from Vertex to Vertex.
       FuncValue is a Value.
    2. A new type named "SimpleFn" will hold a function from Value to
       Value. SimpleFn is not a Value.

    This commit replaces occurrences of the old FuncValue with one of
    those two new types, as appropriate. This commit does not yet adapt
    the surrounding code to make use of the new representation; that
    will be done in future commits. I have annotated the missing parts
    with the following panic message in order to make it easy to find
    which parts still need to be implemented. The "..." part explains
    what needs to be implemented.

        panic("TODO [SimpleFn]: ...");

Here's where I need help:

    One part of the code which is not clear to me are the parts which
    use reflection. I don't understand the purpose of that code well
    enough to explain what needs to be implemented. I have annotated
    those "known unknown" parts of the remaining work with the following
    panic message in order to make it easy to find which parts still
    need more thinking and planning:

        panic("TODO [SimpleFn] [Reflect]: ...");

This is the commit message #2:

lang: Add the core func graph Txn API

This will eventually let functions change the running graph via a
transaction API.

At the moment the core Lock and Unlock primitives aren't implemented.

This is the commit message #3:

lang: A reversible wrapper around Txn

This is useful for the common case in which we call one FuncValue to
construct a bunch of nodes, and later we switch to a different FuncValue
and so we want to remove all the nodes added by the first FuncValue and
replace them by the nodes added by the second FuncValue.

This is the commit message #4:

lang: move FuncValue to its own package

This is the commit message #5:

lang: combine lang/func/structs and ast

Merging those two packages allows us to avoid import cycles when a
Func needs to add an Expr to the graph.

This is the commit message #6:

lang: CallExpr must generate a subgraph

FuncValues are now manipulating the graph instead of manipulating
values, so the logic for calling a FuncValue must now follow suit.

This is the commit message #7:

lang: ExprFunc does not need to store its value

This is the commit message #8:

spelling

This is the commit message #9:

convert between SimpleFn, FuncValue, and Func

This is the commit message #10:

no need for ExprCall.argVertices

it's the exact same thing as ExprCall.Args

This is the commit message #11:

ExprFunc.Func()'s three cases

This is the commit message #12:

FunctionFunc is no longer used

This is the commit message #13:

ExprBool.MergedGraph()

This is the commit message #14:

ExprIf.MergedGraph()

This is the commit message #15:

ExprFunc.MergedGraph()

This is the commit message #16:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Expr interface. The txn type is
interface{} until we have that merged.

This is the commit message #17:

lang: ast, interfaces: Add MergedGraph signature and implementation

This adds a MergedGraph signature to the Stmt interface. The txn type is
interface{} until we have that merged.

This is the commit message #18:

Use MergedGraph signature and implementation

This puts it into play, but doesn't initialize the input args at all.

This is the commit message #19:

Restore ExprBool.Graph() and Func()

This reverts commit 3ea3845.

This is the commit message #20:

Restore ExprIf.Graph()

This reverts commit a62889e.

This is the commit message #21:

restore ExprFunc::Graph() and Func()

This is the commit message #22:

fix type errors

This is the commit message #23:

ExprCall.MergedGraph()

This is the commit message #24:

a more precise type for args

This is the commit message #25:

GraphTxn

This is the commit message #26:

ReversibleTxn.AddGraph

This is the commit message #27:

ExprFunc.MergedGraph()

This is the commit message #28:

ExprVar.MergedGraph()

This is the commit message #29:

sub-graph is spelled subgraph in this codebase

This is the commit message #30:

ExprFunc.mkFunc() was unused

This is the commit message #31:

CallFunc.Stream() should add Funcs to the graph, not Exprs

This is the commit message #32:

move ConstFunc to lang.funcs

This is the commit message #33:

move conversion functions to lang.funcs.simple

I wrote some conversion functions from SimpleFn to FuncValue to Func,
and I want to call them from Func.Stream() implementations, so those
conversion functions should be somewhere in lang.funcs.

This is the commit message #34:

it is the responsibility of the function engine to call Init on the nodes

This is the commit message #35:

FuncValue.Call()

This is the commit message #36:

drop MergedGraph's unused txn parameter

This is the commit message #37:

move CallFunc to funcs.simple

This is the commit message #38:

Func from channel

This is the commit message #39:

ChannelBased{Source,Sink}Func

This is the commit message #40:

MapFunc

This is the commit message #41:

remove unused CallFunc field

This is the commit message #42:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #43:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #44:

extend environment with StmtProg's local variables

This is the commit message #45:

delete unused VarFunc

This is the commit message #46:

appease govet

This is the commit message #47:

add imported variables to the environment

This is the commit message #48:

add builtins to the environment

This is the commit message #49:

accumulate all the imported variables

previously, we were only keeping the imported variables from the last
import statement.

This is the commit message #50:

XXX: wip new function engine

This is the commit message #51:

comments

This is the commit message #52:

remove Engine.{Lock,Unlock} placeholders

This is the commit message #53:

f(...) support for ExprCall

This is the commit message #54:

[REVERT ME] remove unrelated files to make VS Code happy

This is the commit message #55:

don't recreate the subgraphInput

This is the commit message #56:

CallFunc now takes a single input, the FuncValue

Also, by using the map_func logic, CallFunc now detects when it can no
longer emits new values downstream.

This is the commit message #57:

GraphTxn must take a pointer in order to modify the graph

This is the commit message #58:

GraphTxn is unused
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants