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

Cascade implicit block hides missing do syntax errors #179

Closed
qqueue opened this issue Oct 15, 2012 · 9 comments
Closed

Cascade implicit block hides missing do syntax errors #179

qqueue opened this issue Oct 15, 2012 · 9 comments

Comments

@qqueue
Copy link

qqueue commented Oct 15, 2012

a
 b
  c
   d
    e

compiles to

var x$, y$, z$, z1$;
x$ = a;
y$ = b;
z$ = c;
z1$ = d;
e;

even though the cascadee isn't used. This hides some typos involving a missing do that were previously caught at compile time, such as:

method
   arg1
   arg2
var x$;
x$ = method;
arg1;
arg2;

and even though this works when run, it hides the fact that |> doesn't actually accept an implicit block:

program = @createProgram! |>
    @attachShader _, vertex-shader
    @attachShader _, fragment-shader
    @linkProgram _
    unless @getProgramParameter _, LINK_STATUS
      throw new Error "couldn't intialize shader program!"
    @useProgram _
var x$, program, _;
x$ = (_ = program = this.createProgram(), this.attachShader(_, vertexShader));
this.attachShader(_, fragmentShader);
this.linkProgram(_);
if (!this.getProgramParameter(_, LINK_STATUS)) {
  throw new Error("couldn't intialize shader program!");
}
this.useProgram(_);

Proposal: cascade blocks in which the cascadee isn't used at least once should be invalid syntax. The error message should be similar to "Unexpected INDENT on line xx:xx, did you forget a 'do' or a cascade usage?"

@qqueue
Copy link
Author

qqueue commented Oct 15, 2012

Also regarding the last example, it only works because |> binds to the actual _ variable for the rest of the scope, which--though I haven't personally run into this problem yet--also affects the use of underscore.js' default binding:

_ = require \underscore
thing.create! |>
  _.foo!

_.map [1,2,3] -> it.toString! # probably won't work
var _;
_ = require('underscore');
_ = thing.create();
_.foo();
_.map([1, 2, 3], function(it){
  return it.toString();
});

@satyr
Copy link
Owner

satyr commented Oct 15, 2012

Or maybe ditch this syntax and stick with with as per #172.

effects the use of underscore.js' default binding

That's just a naming issue. You should be doing L = require \lodash anyway. ;)

@qqueue
Copy link
Author

qqueue commented Oct 16, 2012

Using with does require an arduous 5 extra characters though.

Perhaps for the minimal case of cascading when you don't need the cascadee as the result, |> could be overloaded as the operator, so this would actually compile as expected, without an extra do:

program = @createProgram! |>
    @attachShader (&), vertex-shader
    @attachShader (&), fragment-shader
    @linkProgram (&)
    unless @getProgramParameter (&), LINK_STATUS
      throw new Error "couldn't intialize shader program!"
    @useProgram (&)
x$ = program = this.createProgram()
this.attachShader(x$, vertexShader));
this.attachShader(x$, fragmentShader);
this.linkProgram(x$);
if (!this.getProgramParameter(x$, LINK_STATUS)) {
  throw new Error("couldn't intialize shader program!");
}
this.useProgram(x$);

The need to wrap & in this use case still sucks though, per #170.

But hey, if the issues with & can be resolved, you could even change the, uh, pipee to & and solve the underscore clobbering problem as well.

thing |> & + & |> &trim! |> [&, &, &]

Maybe do LiveScript's .&. wrapping thing for the real bitwise AND.

@satyr
Copy link
Owner

satyr commented Oct 16, 2012

The two don't merge well. Pipe returns the right hand result where cascade the cascadee (#172).

Maybe do LiveScript's .&. wrapping thing for the real bitwise AND

That's a no-no. We want no more cognitive overhead against JS.

@qqueue
Copy link
Author

qqueue commented Oct 16, 2012

Pipe returns the right hand result where cascade the cascadee

But the cascade in it's current form is essentially the statement version of the pipe:

thing_pipe = ->
  thing |> do
    _.stuff
    foo _
    bar _, baz

thing_cascade = ->
  thing
    &stuff
    foo (&)
    bar (&), baz
var thing_pipe, thing_cascade;
thing_pipe = function(){
  var _;
  _ = thing;
  return _.stuff, foo(_), bar(_, baz);
};
thing_cascade = function(){
  var x$;
  return (x$ = thing, x$.stuff, foo(x$), bar(x$, baz));
};

The |> do form is practically the same as the cascade, and in statement position could certainly be compiled to statements instead of expressions for readability.

Here's another thought: Change the cascadee and pipee to @, and override the shortcut to this within cascades and pipes. @ doesn't have the problems & does, while retaining the single character benefit, and this can still be referenced by its full name if it needs to.

thing |> @ + @ |> @trim! |> [@, @, @]

@satyr
Copy link
Owner

satyr commented Oct 17, 2012

But the cascade in it's current form is essentially the statement version of the pipe

Not in the next version. See the conclusion of #172.

Change the cascadee and pipee to @, and override the shortcut to this within cascades and pipes

Seems way too complicated.

@qqueue
Copy link
Author

qqueue commented Oct 17, 2012

Seems way too complicated

But more, or less complicated than

thing.create!
  & & &

? It's pretty hard to say.

In any case, the main issue of this bug is the tendency of the cascade's implicit block to hide missing do syntax errors for call arguments. Is that implicit cascade going away in favor of #172? If so, this bug is dependent on that, leaving these other items:

  1. pipe clobbers the real _ variable
  2. Should the pipe be able to take an implicit block on the right so |> do is shortened to |>? I still think it's useful when the cascadee shouldn't be the result, and |> is shorter than with.

Do you want separate issues for these?

@vendethiel
Copy link
Contributor

Was & really the best symbol ? I thought about *, which has sense too. Else, well', there's still % or ^ or § or ...

@satyr satyr closed this as completed in 861b442 Oct 17, 2012
@satyr
Copy link
Owner

satyr commented Oct 17, 2012

& & &

Only syntactically complicated. this/@ is semantically complicated in plain JS already, so we don't want to mess with them further.

implicit cascade going away in favor of #172?

Nope, as this proposal is resolved.

Do you want separate issues for these?

Yup, as they surely are separate.

I thought about *, which has sense too

Overused already.

there's still % or ^ or § or ...

%: Viable, but no better than & which I preferred.
^: Taken.
§: Hard to type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants