-
Notifications
You must be signed in to change notification settings - Fork 2k
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
With Statement #620
Comments
The If you really don't want to use a temporary variable, you can always cook up something like this instead:
|
We have several dsls in javascript, and some of them are incredibly more readable in with statement. For instance:
Instead of your old fashioned overly verbose, full of noise: This example is from a port of Ruby's Erector to JS, which we are building, and plan to make open source shortly. We were even considering to switch to coffescript, but the lack of instance_eval and with statement in the language make it a deal breaker. |
|
It is an ok workaround. We'll keep coffesscript on our radar. We'll see if we can change the current nested function style to a Method chaining one. It is important to note that nested function from inherited methods in javascript is quite horrible, as it is in python, because of the obligatory this/self keyword (respectively), which the with keyword removes in js. This is a point where javascript would be actually worse than java in dsls expressiveness, if weren't for 'with(this)'. And I am not even comparing with real pro-dsl languages, such as Scala and Ruby. |
you might want to check out Kaffeine - it's got a similar goal to CoffeeScript, but it's closer to Javascript and doesn't disallow any syntax. Additionally it's got a using plugin that will bring in an objects to the local scope - something that might be useful for your DSLs'. http://github.com/weepy/kaffeine |
Very nice to hear. Definitely considering it. |
Sorry to reopen such an old thread, but I wanted to propose something slightly different. It would make sense in CoffeeScript specifically to support a with Math
result = @floor @max x, y Binding the value of the expression to This fix wouldn't make much sense for JavaScript ( with canvas.getContext "2d"
@fillStyle = "rgb(200, 0, 0)"
@fillRect 10, 10, 50, 50
@fillStyle = "rgba(200, 0, 200, 0.5)"
@fillRect 30, 30, 50, 50 |
@carlsmith Can you add what the intended JavaScript output would be? |
Hey, @GeoffreyBooth. Sure. Assuming with foo then console.log @bar ...would compile to something like... !function() {
console.log(this.bar);
}.bind(foo)(); ... and would log |
Isn't |
I personally think it adds value, and it fulfills an underlying principle of CS, in that it improves a core idea of Ecmascript.
|
We shouldn't re-use (->
@fillStyle = "rgb(200, 0, 0)"
@fillRect 10, 10, 50, 50
@fillStyle = "rgba(200, 0, 200, 0.5)"
@fillRect 30, 30, 50, 50
).call canvas.getContext "2d" |
Not really. That code just assigns the longer name to a shorter name that is automatically cleaned up at the end of the block, which wouldn't be applicable to the original example, as you would just use a shorter name to begin with. It's examples like this that I think const context = canvas.getContext("2d");
context.fillStyle = "rgb(200, 0, 0)";
context.fillRect(10, 10, 50, 50);
context.fillStyle = "rgba(200, 0, 200, 0.5)";
context.fillRect(30, 30, 50, 50); Most developers would use an abbreviation, so would probably do this: const ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200, 0, 0)";
ctx.fillRect(10, 10, 50, 50);
... In these cases, there's no way to apply your suggestion, except to just use an even shorter abbreviation: const c = canvas.getContext("2d");
c.fillStyle = "rgb(200, 0, 0)";
c.fillRect(10, 10, 50, 50);
... It would be nice to get rid of the temporary variable altogether: with canvas.getContext "2d"
@fillStyle = "rgb(200, 0, 0)"
@fillRect 10, 10, 50, 50
... |
@jashkenas' example would work the same way, so yeah, I'd like to use (->
@fillStyle = "rgb(200, 0, 0)"
@fillRect 10, 10, 50, 50
@fillStyle = "rgba(200, 0, 200, 0.5)"
@fillRect 30, 30, 50, 50
).call canvas.getContext "2d" I don't think the pattern is "odd". It's really just doing what |
I’m concerned by the overloading of Most libraries solve this problem through chaining: xAxis = d3.scaleBand()
.rangeRound [0, width]
.padding 0.15, 0.15
.domain data.periodNames I know the vanilla DOM methods don’t chain, and that’s what you appear to be working with; and maybe you don’t want to use jQuery, but there’s probably a simpler library out there that wraps those methods into chainable variants. |
Yeah, on balance, it seems best to just use one of the workarounds. The Thanks for considering this. |
If anyone really ever needs it: _with = (context, args..., block) -> Reflect.apply block, context, args
_with {a: 1, b: 2}, ->
@a * @b
_with canvas.getContext("2d"), this, (self) ->
for {rect, color, bActive} in self.regions when bActive
@fillStyle = color
@fillRect rect...
this |
It would be nice to have with statement on coffescript. Actually, instance eval would be nicer, but with stament is close enough for most dsls.
The text was updated successfully, but these errors were encountered: