Open dead-claudia opened 6 years ago
Yep, indeed. I left this as an extension here:
https://github.com/samuelgoto/proposal-block-params#bindings
WDYT?
Eh...it makes sense in some contexts (like iteration), but not in others (makefile task arguments).
I did read that after I filed this, but that idea really didn't feel right, especially if you have more than one parameter passed to the block (consider task name + dependencies).
Yep, agreed that the syntax needs more work. Can you help me identify what are the most common use cases where you'd want arguments?
especially if you have more than one parameter passed to the block (consider task name + dependencies).
fwiw, in the current formulation,multiple parameters could be set:
foreach ({key, value} in map) {
// ...
}
The most common use cases would be in iteration-like contexts, but not all iteration is synchronous (like above). One example where multiple distinct arguments would be nice would be with native forEach
, which would work out-of-the-box with explicit parameters:
list.forEach do (item, i) {
// Do something that requires both the current item and its index.
}
fwiw, in the current formulation,multiple parameters could be set:
To clarify, I'm speaking about the callee's side, not the callback's side:
task("foo", ["dep1", "dep2"]) do (args) {
// ...
}
While looking at porting some of my own code (a WIP DOM framework) over to use this, I ran into one case, although your binding proposal would work:
// Original
r.dynamic(stream, (r, item) => {
// re-render on each received item
})
// This proposal
dynamic(stream) do (item) {
// re-render on each received item
}
// Binding proposal
dynamic(item in stream) {
// ...
}
Also, previously, I had my components defined like this:
// Original
const Component = m.component((r, attrs, children) => {
// ...
})
// What it could be
const Component = m.component do (attrs, children) {
// ...
}
The most common use cases would be in iteration-like contexts, but not all iteration is synchronous (like above). One example where multiple distinct arguments would be nice would be with native forEach, which would work out-of-the-box with explicit parameters:
list.forEach do (item, i) {
// Do something that requires both the current item and its index.
}
In the current formulation, this is what the syntax would look like:
foreach ({item, index} in list) {
// Do something that requires both the current item and its index.
}
Which would desugar to:
foreach (list, function({item, index}) {
// Do something that requires both the current item and its index.
});
Which foreach
could use to pass parameters to the callee (IIUC your terminology):
function foreach(list, block) {
for (let i = 0; i < list.length; i++) {
block({item: list[i], index: i});
}
}
Would that work?
WIP DOM framework
I would love to hear more about your DOM framework :) This was very much started because I feel in love with Kotlin's examples of DSLs for DOM construction so hoping it will help this area.
Care to share any links?
@samuelgoto
In the current formulation, this is what the syntax would look like: [...]
I'm aware. I was responding with that awareness in mind.
Care to share any links?
It's currently private and purely local, since I'm only just now getting to the beginning stages of implementing the logic, and haven't implemented any tests (after spending literal months figuring out what I wanted the API to be).
Edit: I hided this inside a <details>
element, to make it easier to scroll by.
Edit: I hided this inside a <details>
element, to make it easier to scroll by.
What about the following?
const Toggle = m.component do ({change, name}) {
label({style: {padding: 20px}}]) {
::onclick() { change.send(name) }})
input({type: radio, name: font-size}) {
}
span(name) {}
}
}
I've considered going a similar route to that, except I ran into a few glitches:
this
to discern the difference between the two.Of course, this is more of a hypothetical front-end, and I'm developing a shared backend you can write the front-end stuff based on. It is similar to incremental-dom and virtual-dom in that regard, and you could write your own front-end that works that way.
Mind if you could find me on Gitter, and we can talk more on this privately? I'd rather avoid polluting the issue further on this topic, since it's not even public yet.
Arguments seem pretty important to me, especially with how you have examples with arguments (e.g., under "C#'s foreach").
Bikeshed syntax: maybe it's odd, but could we reuse the arrow function arrow?
foreach(list) item => {
}
Otherwise I like the foreach (map) { |key, value| }
syntax.
I dislike ruby's foreach (map) { |key, value| }
syntax, but I think
foreach(list) item => {
}
or
foreach(list) do (item) {
}
Is growing on me.
May I ask what are your first impressions / reservations for the in
syntax (totally cool if the impressions are purely subjective/bikeshedding)? Doesn't that look more consistent with the current usage of
for (a in list) {
}
Don't you think it feels more natural to re-use that syntax/construct for params?
foreach (a in list) {
}
?
I like either of those too.
My immediate reaction to in
is a little hesitant. It makes me think of a for-in loop, where things would be different in two ways:
Even though it's not supposed to be any of those things, it raises my subconscious JS linter flags.
just as another data point, @erights also suggested the following syntax:
foreach(list) do (item) {
}
Which I think is a reasonable form and seems to map better to people's intuition than my original form. I'm going to update the text to reflect that (done).
SGTM
In many DSLs, it's convenient to have the ability to pass arguments to the callback as well - a good example of this is with arguments for a makefile task, but also, most of the binding-related stuff could be addressed similarly by simply accepting arguments.
My first instinct would be something like this (obvious Ruby inspiration):