Why is this Coffeescript invalid? - coffeescript

I'm playing around with Coffeescript, trying to convert a JavaScript file to Coffeescript. This is valid JavaScript:
element(by.model('query.address')).sendKeys('947');
This is invalid Coffeescript:
element(by.model('query.address')).sendKeys('947')
What is invalid about the Coffeescript? Coffeelint says "unexpected BY".

CoffeeScript uses the by keyword to let you use a specific step when looping through a range.
From the documentation:
To step through a range comprehension in fixed-size chunks, use by, for example:
evens = (x for x in [0..10] by 2)
Since JavaScript doesn't use by it's valid. For CoffeeScript, try renaming the by to something else.
In response to the comment, since Protractor provides its own by global variable, one idea is to alias it via CoffeeScript's embedded JavaScript syntax (code surrounded by back-ticks), then continue using CoffeeScript and the alias throughout your code.
You'll need to test this type of code:
ptorBy = `by`
element(ptorBy.model('query.address')).sendKeys('947')
Where ptor is just my short-hand for "Protractor." This translates to the following JavaScript:
var ptorBy;
ptorBy = by;
element(ptorBy.model('query.address')).sendKeys('947');

Related

Spread syntax in function call in Reason

In Javascript you can use the spread syntax in a function call like this:
console.log(...[1,2,3]);
Is there an equivalent in Reason? I tried the following:
let bound = (number, lower, upper) => {
max(lower, min(upper, number));
};
let parameters = (1,0,20);
bound(...parameters) |> Js.log;
But this gives an unknown syntax error:
Try reason snippet
There's not. Reason is a statically typed language, and lists are dynamically-sized and homogenous. It would be of very limited use, and not at all obvious how it would deal with too few or too many arguments. If you want to pass a list, you should just accept a list and deal with it appropriately, as a separate function if desired.
You could of course use a tuple instead, which is fixed-size and heterogenous, but I don't see a use-case for that either, since you might as well just call the function directly then.
For JavaScript FFI there is however the bs.splice attribute, which will allow you to apply a variable number of arguments to a js function using an array. But it needs to be called with an array literal, not just any array.

How to safely manipulate MATLAB anonymous functions in string form

I have an anonymous function that I would like to manipulate in string form then use with fsolve.
When I do this the references in the anonymous function to constants are lost and fsolve fails.
The problem is easily illustrated.
The following works:
A=3;
myfun=#(x)sin(A*x);
x = fsolve(#(x)myfun(x),[1 4],optimoptions('fsolve','Display','off'))
The following throws an error as explained here:
A=3;
myfun=#(x)sin(A*x);
mystring=func2str(myfun);
%string operations would go here such as strrep(mystring,'A','A^2') or whatever
myfun2=str2func(mystring);
x = fsolve(#(x)myfun2(x),[1 4],optimoptions('fsolve','Display','off'))
Is there some way I CAN safely manipulate an anonymous function while retaining references to constant parameters?
more info
Specifically I'm writing a simple wrapper to allow fsolve to accept imaginary numbers for simple cases. The following illustrates a working example without a constant parameter:
myeqn=#(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
f1=strrep(func2str(myeqn),'#(x)','');
f2=strrep((f1),'x','(x(1)+(x(2))*1i)');
f3=strcat('#(x)[real(',f2,'); imag(',f2,')]');
fc=str2func(f3);
opts=optimoptions('fsolve','Display','off');
result=arrayfun(#(cinput)[1 1i]*(real(fsolve(fc,[real(cinput);imag(cinput)],opts))),cX0)
As in the failed example above if I include a parameter in my wrapper the process fails with the same error as above.
I originally suggested to use the symbolic math toolbox, but reading your question again I realized it's just a simple substitution of input parameters. You can achieve this using function handles without any string processing.
myeqn=#(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
wrapper=#(x,f)([real(f(x(1)+x(2)*i)),imag(f(x(1)+x(2)*i))])
opts=optimoptions('fsolve','Display','off');
result=arrayfun(#(cinput)[1 1i]*(real(fsolve(#(x)wrapper(x,myeqn),[real(cinput);imag(cinput)],opts))),cX0)
As much as I hate to suggest using the eval function, you could do:
myfun2 = eval(mystring);
Using eval is kinda frowned upon because it makes code hard to analyze (since arbitrary nastiness could be going on in that string), but don't let other people's coding style stop you from doing what works :)
In your longer example, this would correspond to changing the line:
fc=str2func(f3);
to:
fc=eval(f3);
Again, the use of eval is strongly discouraged, so you should consider alternatives to this type of string manipulation of function definitions.

What's the meaning of this line of CoffeeScript?

I was reading through the Journo's source code and I stumbled upon this line of code:
markdown = _.template(source.toString()) variables
What is variables doing here? Is _.template(source.toString()) variables valid stntax at all?
Here's the function wrapping that line of code:
Journo.render = (post, source) ->
catchErrors ->
do loadLayout
source or= fs.readFileSync postPath post
variables = renderVariables post
markdown = _.template(source.toString()) variables
title = detectTitle markdown
content = marked.parser marked.lexer markdown
shared.layout _.extend variables, {title, content}
Yes, it is valid. Parenthesis are optional (sometimes) in CoffeeScript when invoking a function, so it is taking the result of template and invoking it with arguments. It compiles to this JavaScript:
_.template(source.toString())(variables);
From the CoffeeScript documentation:
You don't need to use parentheses to invoke a function if you're passing arguments. The implicit call wraps forward to the end of the line or block expression.
_.template compiles a template specified by source.toString(). A template is a function, which is then called. variables is a parameter for that function (just like postPath post are parameters for fs.readFileSync).
See also the docs for _.template
The question was nicely answered, but to help the OP with future coffee stunts, a great way to anser these koans is to
Go to the coffeescript.org site
Click on "Try coffeescript"
Cut/Paste the puzzle into the coffeescript section
Bingo! You see the generated javascript.
I admit to puzzling over coffeescript at times, and this is abs fab .. and saves headaches.

Add a new assignment operator

I started using smalltalk and I am trying to add a new assignment operator :>.
The current operator used in pharo is no selector so I started to look into the class Scanner where the underscore _ can be enabled for assignments. I've tried to do it in a similar way but it did not work.
Do you have any idea or suggestion about how I achieve that?
For a start, have a look at the Method Scanner>>#xColon. This method is called whenever a colon is encountered in the input. By adding the following snippet to the top of the method, you can make it detect your new assignment token :>:
aheadChar = $> ifTrue: [
self step.
tokenType := #leftArrow.
self step.
^ token := #':=' ]
Like this :> behaves exactly like the normal assignment. By customising tokenType and token you can pass your new assignment operator to the parser (see Parser>>#expression and Parser>>#assignment:) and build a different AST (i.e. to achieve a different execution behaviour).
If you are interested in more flexibility you might want to look at Helvetia. Helvetia is a language workbench for Pharo that allows you to modify the host language and adapt the tools in a more modular fashion. One of the examples included with the distribution (CUSwapExample) is adding two new assignment operators to Smalltalk.

How to use Javascript's for (attr in this) with Coffeescript

In Javascript, the "for (attr in this)" is often dangerous to use... I agree. That's one reason I like Coffeescript. However, I'm programming in Coffeescript and have a case where I need Javascript's "for (attr in this)". Is there a good way to do this in Coffeescript?
What I am doing now is writing a bunch of logic in embedded raw Javascript, such as:
...coffeescript here...
for (attr in this) {
if (stuff here) {
etc
}
}
It'd be nice to use as little Javascript as possible... any suggestions for how I can achieve this and maximize my use of Coffeescript?
Instead of for item in items which iterates through arrays, you can use for attr, value of object, which works more like for in from JS.
for own attr, value of this
if attr == 'foo' && value == 'bar'
console.log 'Found a foobar!'
Compiled: https://gist.github.com/62860f0c07d60320151c
It accepts both the key and the value in the loop, which is very handy. And you can insert the own keyword right after the for in order to enforce an if object.hasOwnProperty(attr) check which should filter out anything from the prototype that you don't want in there.
Squeegy's answer is correct. Let me just amend it by adding that the usual solution to JavaScript's for...in being "dangerous" (by including prototype properties) is to add a hasOwnProperty check. CoffeeScript can do this automatically using the special own keyword:
for own attr of this
...
is equivalent to the JavaScript
for (attr in this) {
if (!Object.prototype.hasOwnProperty(this, attr)) continue;
...
}
When in doubt about whether you should use for...of or for own...of, it's generally safer to use own.
You can use for x in y or for x of y depending on how you want to interpret a list of elements. The newest version of CoffeeScript aims to solve this problem, and you can read about its new use with an issue (that has since been implemented and closed) here on GitHub