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

All iterated ComputationExpressions (CE returning CE builders) #799

Open
krauthaufen opened this issue Oct 23, 2019 · 6 comments

Comments

@krauthaufen
Copy link

@krauthaufen krauthaufen commented Oct 23, 2019

Change ComputationExpression associativity

I propose we change the associativity for ComputationExpression builders. This is only relevant in extreme corner cases where CE builders return other CE builders in their Run method.
This currently prohibits the use of chained CEs like:

// currenlty not compiling
node { "a", "somevalue" } {
    leaf { "b", "foo" }
    leaf { "b", "foo" }
}

Here's a more complete example including the relevant parts of the builders:

type Node = Node of Map<string, string> * list<Node>

type SubNodeBuilder(attributes : Map<string, string>) =
    // ...
    member x.Yield(node : Node) = [node]
    member x.Run f = Node(attributes, f)

type NodeBuilder() =
    // ...
    member x.Yield(name : string, value : string) = Map.ofList [name, value]
    member x.Run f = SubNodeBuilder(f)
    
type LeafBuilder() =
    // ...
    member x.Yield(name : string, value : string) = Map.ofList [name, value]
    member x.Run f = Node(f, [])


let node = NodeBuilder()
let leaf = LeafBuilder()

// currenlty not compiling
node { "a", "somevalue" } {
    leaf { "b", "foo" }
    leaf { "b", "foo" }
}

// currently braces are needed to ensure that the
// expression gets interpreted correctly.
(node { "a", "somevalue" }) {
    leaf { "b", "foo" }
    leaf { "b", "foo" }
}

Complete code can be found at https://gist.github.com/krauthaufen/199ff3a620fbc820dcf2f2d2174bdce5

The existing way of approaching this problem in F# is by not using CE builders like that.

Pros and Cons

The advantages of making this adjustment to F# are that embedding custom languages for e.g. HTML-DOMs would get more flexible.
Together with implicit yields these EDSLs would syntactically look very similar to their current list based counterparts.

The disadvantages of making this adjustment to F# are that code may break that relies on the current interpretation of this, although I'm not sure if there actually is a way of using this for good.

Extra information

Estimated cost XS

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this
@dsyme

This comment has been minimized.

Copy link
Collaborator

@dsyme dsyme commented Oct 24, 2019

This seems like a reasonable change, the left-associative approach is the correct one. (To be honest I'd never even considered the case of a CE returning a CE builder... Interesting indeed....)

@abelbraaksma

This comment has been minimized.

Copy link

@abelbraaksma abelbraaksma commented Oct 24, 2019

Wouldn't this create a backwards incompatible issue? And if so, is that risk acceptable?

@dsyme

This comment has been minimized.

Copy link
Collaborator

@dsyme dsyme commented Oct 24, 2019

Wouldn't this create a backwards incompatible issue? And if so, is that risk acceptable?

I'm not actually sure there is an issue, but yes, I think it would be acceptable. It's basically a bug fix. Is there an example of code that would no longer continue to function?

@krauthaufen

This comment has been minimized.

Copy link
Author

@krauthaufen krauthaufen commented Oct 24, 2019

I couldn't come up with a compiling example yet...
basically what you have is ce ({ ... } { ... }) and I think the expression ({ ... } { ... }) will never compile in FSharp will it?

@dsyme

This comment has been minimized.

Copy link
Collaborator

@dsyme dsyme commented Oct 24, 2019

I think the expressions ({ ... } { ... }) will never compile in FSharp will it?

Correct

@dsyme

This comment has been minimized.

Copy link
Collaborator

@dsyme dsyme commented Oct 24, 2019

Note I don't think the compiler is actually trying to process that. It's just refusing to apply CE rules repeatedly over curried application f { ... } { ... } - it's only applying them to f { ... }. Strictly speaking this is probably according to spec so it's not a bug fix, rather a new case

@dsyme dsyme changed the title Change ComputationExpression associativity All iterated ComputationExpressions (CE returning CE builders) Oct 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.