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

Domain Specific Languages and Extension Functions #1978

Open
Oliver-makes-code opened this issue Aug 10, 2022 · 5 comments
Open

Domain Specific Languages and Extension Functions #1978

Oliver-makes-code opened this issue Aug 10, 2022 · 5 comments
Labels
leads question A question for the leads team long term Issues expected to take over 90 days to resolve.

Comments

@Oliver-makes-code
Copy link

Here's a proposal for Domain Specific Languages (DSLs), and by proxy, Extension Functions.

In Kotlin and C#, an extension function/method allows you to create functions/methods that take place in the context of a class, while not directly being a member of the class. See the Kotlin and Java code below for an example

// This kotlin code
fun String.foo() {
    println(this)
}
// Corresponds to this Java code
public void foo(String thiz) {
    System.out.println(thiz);
}

This allows you to call String.foo() in Kotlin (as Java doesn't have extension functions) and it will run the code inside the extension function.

Another concept in Kotlin, and a couple other languages, is the DSL. Kotlin's implementation passes a function reference, usually an extension function, into the parameters, and calls that function on the DSL class. Provided below is an example

// DSL class
class FooDsl {
    fun bar() {
        println("Called bar!")
    }
    fun baz() {
        println("Called baz!")
    }
}

// Runs the DSL
fun fooDsl(block: FooDsl.() -> Unit /*This is an extension function reference*/): FooDsl {
    val dsl = FooDsl()
    // Call block on the DSL
    dsl.block()
    // Return the DSL with the block applied
    return dsl
}

// Calls the DSL
fun callDsl() {
    fooDsl {
        // Calls FooDsl.bar
        bar()
        // Calls FooDsl.baz
        baz()
    }
}

Adding these concepts to Carbon would help modernize the language, and to stand out more from C++ or Rust

@geoffromer
Copy link
Contributor

See #1122 for a previous attempt to add extension methods to Carbon. In particular, the section on "Problems with extension methods" discusses some issues that any proposal in this space will need to address. It will probably also be important to articulate what problems these features would solve -- "modernize" is pretty vague, and "standing out more from C++" arguably goes against our C++ interop and migration goal.

@Oliver-makes-code
Copy link
Author

Oliver-makes-code commented Aug 10, 2022

"standing out more from C++" arguably goes against our C++ interop and migration goal.

Kotlin keeps interop with Java in this context by having the method signature have the class it's adding to as the first parameter

fun String.foo() would have the method signature foo(Ljava/lang/String;)V

@JamesJCode
Copy link

We have discussed the block-like syntax (as shown for DSLs) fairly extensively in the context of it being a candidate syntax for lambdas, and also the associated plumbing to make it work, such as implicit block parameters, receiver objects, scoped return statements etc.

We have taken the view for the time being to focus on an 'MVP' of explicit lambdas, with both terse (e.g. for algorithm predicates) and verbose (generics, capture specifiers, explicit arguments, etc) syntaxes.

This is not to say we won't revisit the block-like approach, it just has a whole load of couplings that need to be considered, along with some readability and usibility concerns.

@geoffromer
Copy link
Contributor

"standing out more from C++" arguably goes against our C++ interop and migration goal.

Kotlin keeps interop with Java in this context by having the method signature have the class it's adding to as the first parameter

Sure, there are probably plenty of ways to address the interop/migration concerns. My point was just that "standing out from C++" isn't a compelling rationale for adding this feature, because it's at best a non-goal, and at worst an anti-goal.

@github-actions
Copy link

github-actions bot commented Nov 9, 2022

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the inactive label. The long term label can also be added for issues which are expected to take time.
This issue is labeled inactive because the last activity was over 90 days ago.

@github-actions github-actions bot added the inactive Issues and PRs which have been inactive for at least 90 days. label Nov 9, 2022
@jonmeow jonmeow added long term Issues expected to take over 90 days to resolve. leads question A question for the leads team and removed inactive Issues and PRs which have been inactive for at least 90 days. labels Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
leads question A question for the leads team long term Issues expected to take over 90 days to resolve.
Projects
None yet
Development

No branches or pull requests

4 participants