Code Monkey home page Code Monkey logo

rapydscript's Issues

src/lib/output.pyj: 583: mixin: "taget" used instead of "target"

Type on line 583: parens: [ "overwrite", "||", "typeof", "taget[i]", "===", '"undefined"' ]

Result: emits "typeof taget[i]", instead of "typeof target[i]"

function _$rapyd$_mixin(target, source, overwrite) {
for (var i in source) {
if (source.hasOwnProperty(i) && (overwrite || typeof taget[i] === "undefined")) target[i] = source[i];
}
}

web2py hello world example?

hello can you post a litle sample on how to use it inside web2py?

i installed rapydsript globally but i cant seem to find a way to have your

def greet():
alert("Hello World!")

working in a web2py view

Thank you

Parser line number in error messages is off when triple-quoted strings are present

With any triple-quoted strings, e.g. docstrings or JS(""" , the line number counter is apparently not incremented.

Result: WARN: ERROR messages send user to the wrong line.

class foo:
        def __init__(self):
                """
                This comment spans 3 lines.
                """
pass
        def bar(self): # Will warn of inconsistent indentation on line 4 instead of 7.
                pass

WARN: ERROR: Inconsistent indentation [test.py:4,0]

"use strict" by default

Having done some research, I realized that there are almost no cases where code compiled in strict mode is incompatible with original JavaScript (with the exception of one special case in IE8: http://stackoverflow.com/questions/18223517/is-it-safe-to-use-use-strict-in-ie-8-9). Moreover, several features of strict mode appealed to me as more 'Pythonic', or rather enabling a typical Python developer to write better JavaScript and catch errors early:

  • multiple silent "errors" where JavaScript would ignore the command without letting the user know that now raise assertions (this is great for those who prefer Python's try/except approach)
  • the above bullet has an added benefit of making getters/setters work saner, allowing us to eventually make this part of the language core
  • an additional safety check against using globals (RS already handles this quite gracefully, but this will prevent a frustrated newbie from doing something along the lines of 'nonlocal *')

Additionally I was looking for potential problems/incompatibilities of strict mode with RS, and couldn't find any, so I'm for it. I will add a flag to let people undo it in case I break something for local projects.

kwargs on constructor

The following code:

class test:
    @kwargs
    def __init__(self, a=100, b=200, c=300):
        print(a, b, c)

will compile into:

function test(a, b, c){
    var self = this;
    if (typeof a === "undefined") a = 100;
    if (typeof b === "undefined") b = 200;
    if (typeof c === "undefined") c = 300;
    _$rapyd$_print(a, b, c);
};
test.prototype.__init__ = kwargs(test.prototype.__init__);

Since init doesn't exist, it will break. I'd need to test this further to see if a passthrough of regular constructor through kwargs would work or would introduce other problems with isinstance() and inheritance.

separate out optimization tricks into a separate parser

There are some compile-time optimizations RS already does, here are some examples:

for i in range(n):
    ...
for i in range(n, -1, -1):
    ...
for i in dir(obj):
    ...

Which compile into i++, i--, and for ... in loops respectively. These are scattered and hard to follow in the code. Also, due to them occurring at the time of output, the compiler doesn't have the ability to retroactively modify code that has already been output (i.e. removing the range implementation since the only call to it got optimized out). Moving the optimizer out into its own module would allow it to be more durable, consistent and aggressive.

For example, in addition to optimizing [1 to 5] to range(1, 5), we could also optimize it to [1,2,3,4,5] because both start and end are constants.

Using the variable name 'module' triggers a parse error

The minimum code to reproduce this:

module = def(test):
    print(test)

The trace:

WARN: ERROR: Name expected [test.pyj:3,0]

/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:122
    throw new JS_Parse_Error(message, line, col, pos);
          ^
Error
    at new JS_Parse_Error (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:110:18)
    at js_error (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:122:11)
    at croak (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:702:9)
    at as_symbol (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:1974:17)
    at module_ (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:1259:38)
    at /home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:936:24
    at /home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:742:20
    at Object.<anonymous> (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:2320:23)
    at Object.parse (/home/lool0/grunt-test/lib/node_modules/rapydscript/lib/parse.js:2362:7)
    at /home/lool0/grunt-test/lib/node_modules/rapydscript/bin/rapydscript:241:36

I suppose this is a reserved word in rapydscript, but overriding things on module.exports happens to be a thing that you'd wanna do in a node app. Is using rapydscript in node.js apps not encouraged?

Named Parameters

Currently, named Arguments in functions are translated to Javascript, as if they worked just the same in Javascript as in Python. Sadly they don't. The following Example:

def Vehicle(doors=2, wheels=4, windows=4):
    console.log(doors, wheels, windows)

car = Vehicle(windows=6)

... is translated into the following JavaScript:

function Vehicle(doors, wheels, windows) {
    if (typeof doors === "undefined") doors = 2;
    if (typeof wheels === "undefined") wheels = 4;
    if (typeof windows === "undefined") windows = 4;
    console.log(doors, wheels, windows);
}

car = Vehicle(windows = 6);

My IDE says "Variable windows implicitly declared".
The Output is:

>>> 6 4 4

... when of cause it should be 2 4 6.

There are several workarounds floating around in JavaScrpt but RapydScript could handle this much easier without breaking compatibility. RapydScript could look up in which order the parameters are expected and put them in the right order, so

car = Vehicle(windows=6)

would become

car = Vehicle(null, null, 6);

Support for ES6 functions

ECMAScript 6 is almost finished, supported by Firefox and can be used today with ES6 Shim:
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
https://developer.mozilla.org/en-US/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla
https://github.com/paulmillr/es6-shim/

It would be nice if RapydScript could support some static functions. For example:
'String': {static: ['fromCharCode', 'fromCodePoint', 'raw']},
'Array': {static: ['from', 'isArray', 'of']},
'Number': {static: ['isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'parseFloat', 'parseInt']},
'Date': {static: ['now', 'parse', 'UTC']},

(Some functions are from older version of ES, two of them are in current master.)

** operator

Not a big fan of having multiple ways of doing the same thing, but adding this operator in as a synonym for Math.pow() per Bruce's request from GlowScript community. Since python already supports this operator, and there is no ambiguity regarding it's meaning in JavaScript, I feel it's safe to add it in.

hanging-indent form "do and while " doesn‘t work

this is an example from README.md Chaining Blocks, but it cannot be parsed to js

a = 0
do and while a < 1:
    print(a)
    a += 1

WARN: ERROR: Unexpected token: operator «&&» [loops.pyj:2,3]

Is there a problem?

optimize += 1 and -= 1

Minor, but JavaScript uses ++ and -- for these, this saves us an extra character in generated code and an extra symbol for interpreter (binary op + operand vs unary op).

...Tried to email you, but received a failed message

...so here's a copy/paste of it

Alexander,

I can't tell you how happy I was when I wrote up:

class Foo:
  def __init__(self):
    console.log("foo")

  def bar(self):
    console.log("baz")

f = Foo()
f.bar()

...and saw it perfectly working with RapydScript (Node and in browser). Thank you for your hard work on this tool... Python is my favorite language, but when writing JS, CoffeeScript is way too weird for me and writing in JS (even with ES6) is still a pretty bad experience.

3 quick questions for you:

  1. Have you considered renaming the project to something a bit more marketable? Something like "PythonScript" or "PythonJS" kind of like what Golang is doing with its https://github.com/gopherjs/gopherjs ?

  2. (This is just me being lazy and asking before I've tried it) but have you successfully hooked up RapydScript with something like Jasmine successfully?

  3. Transpilers can be slow, of course. From the demos I'm compiled with RapydScript, it seems pretty fast. Have you seen it working at a good performance with larger codebases? Like 10K+ LoC of RapydScript?

Thanks!

Matthew Vita
www.matthewvita.com

No string interpolation

No string interpolation at all (neither "%s" % "foo", nor "{}".format("foo") severely limits usefulness. And no, a different synax (`vsprintf``) doesn't cut it. Just too unpythonic ..

add linter stage in compilation

In addition to optimizer (#39), RapydScript could use a linter. There are certain design patterns that are harmful in JS. Sometimes it's easy to detect when developer is doing something funky by looking at the code, even for an automated tool. Yet we do not want to cause an error in these cases due to a small possibility of false positive. For cases like this, I'd like to add a linter stage, that will warn about potential bugs in the code but can easily be silenced by the developer. For example, the following pattern is 90% likely to be a bug (regular equality check on array) and can easily be warned about by the linter:

def scope():
    a = [...]
    ... # no assignment to a here
    if a == ...:
       ...

Similarly:

def scope():
    a = [...] # explicitly defined length (n)
    ... # number of push/append operations can be bound to m
    a[k] # use of a[k] for purposes other than assignment where k > m+n

In fact, in the above scenario, the assignment to a[k] may itself be flagged as bad and a.push() be preferred due to its inability to push elements out of order, in which case the following anti-pattern would also be flagged against by the linter:

def scope():
    a = [...] # explicitly defined length (n)
    ... # number of push/append operations can be bound to m
    a[k] = ... # where k > m+n

Likewise, the following can be warned against in case developer meant to do a check against undefined:

if a != None:
    ...

Additionally patterns like this, which would result in number concatenation rather than addition and can easily be silenced via the use of str():

'string' + 1 + 2

Also, the following pattern may be indicative that the user did something they did not intend to do:

def func(..., a, **kw):
    ... # do something with a

Because kw has been defined but unused (this may also apply to other arguments for the function), suggesting that user either mistakenly assumed that a will alias kw.a like in Python without @kwargs decorator or did not intend kw to be in the input.

Another anti-pattern:

def scope():
    a = [...]
    ...
    a['string'] = ... # using array as a dict

Yet another bug that linter can catch:

def scope():
    a = [...]
    ...
    a + ... # concatenating arrays in JS will stringify them

The above can be extended to functions/objects as well, really + only makes sense on strings/numbers in JS, and once the linter is sure the object is neither, it can safely raise a red flag. - only makes sense on numbers.

A more dangerous, yet useful feature for the linter could be attempting to match up function calls against signature when possible (duck typing makes this possible, but in some cases you can be pretty certain which call is being referred to). If such match is made, the linter can do additional gut checks:

  • does function even exist?
  • does the number of arguments being passed match? Every optional argument must have a default specified
  • do argument types match when type can be reasonably inferred? For this, the linter can make a sane assumption that None is ok substitute for any type, but strings/numbers/arrays/hashes/functions are not interchangeable (this may also be an optional flag for more advanced linting or kick in when user defines type annotations via Python-3 style)
  • does return signature match?

The above check could be problematic if multiple functions by same name exist within multiple classes, but many can be further remedied/detected by assuming that whatever type was first assigned to a variable will be exclusively used by it.

One potential technique for telling the linter to ignore a certain problem could be a comment:

a['badkey'] = ... # NOLINT: this is intentional

Stricter equality

Several members suggested changing RapydScript's == operator to compile to JavaScript's === operator rather than ==. While I'm at it, I will look into changing is operator to compiler to Object.is() rather than ===.

add dot-operators

There have been a number of threads on the mailing list asking for ability to overwrite RapydScript operators, to which I have objected due to performance and clarity of generated JavaScript. However, I do understand the use case of developers wanting this functionality. Likewise, there are multiple cases where I could find operator overloading useful myself - one of the simplest cases is == test between arrays, which is a notorious problem with JavaScript (and for which RapydScript currently relies on deep_eq).

I've recently been considering adding new operators (even though I'm against adding unpythonic features) to handle these cases. My idea was using the '.' prefix for the operators to signify that they can be overloaded (the names would match their Python equivalent overload names (https://docs.python.org/2/library/operator.html), or perhaps even use the same name as a method name: i.e. 'Array.== = ' which would compile to 'Array.eq').

There are a couple things that appeal to me about the '.' prefix:

  • It's unobtrusive and compact, yet alerts the developer that the operator isn't a standard JS operator
  • '.' is already used to signify a method call of a class/object, these overloadable operators would compile into method calls, hence this seems like a consistent convention

The idea is that each '.' operator would compile into something like this:

original:

a .== b

compiled:

_$rapyd$__eq__(a, b)
function _$rapyd$__eq__(a, b) {
    if (typeof a.__eq__ === 'function') return a.__eq__(b); // user-defined
    return deep_eq(a, b); // default case, a slower but saner equality test

}

The equivalent method would get generated for all operators used (similar to other baselib logic). This, of course, would still require you to tweak your Python code slightly when porting it to RapydScript, but it wouldn't be a tedious task for the few cases that need it. I'm thinking of allowing these alternatives for all operators:
.=, .==, .!=, .<, .>, .+, ./, .*, .-, .and, .or, as well as binary operators

Additionally, I was thinking of introducing a 'debug' mode for compilation, that would, using logic similar to the logic above compile all operators into something safer yet slower, allowing the developer to catch errors earlier. For example:

original:
string + integer

debug compile:
$rapyd__debugadd_(string, integer)
function _$rapyd$debugadd(a, b) {
if (typeof a === typeof b) {
if (typeof a === 'object') throw new TypeError("Concatenation of objects/arrays using + operator will result in implicit conversion to string or NaN, use .+ operator instead");
return a + b;
} else {
throw new TypeError(''Cannot add/concatenate "' + typeof a + '" and "' + typeof b + '" objects');
}
}

As you can see above, debug mode wouldn't rely on the same functions as the '.' prefix, but the structure would be similar. Whereas '.' would check if overloaded method exists, and if not, call the safer/pythonic function, debug would not check overloaded method at all, but would warn the user when the likely intent is to use the safer/pythonic function. The debug mode would run slower but give developer much better sanity checks when the code is executed.

To summarize, there are two ideas here:

  • addition of '.' prefix for each operator to signify overloaded/pythonic version of it without forcing the overhead of pythonic version on all cases
  • addition of debug mode that would rely on similar logic to temporarily overload basic operators during a debug build for stricter type checking

npm install error

Ran this command from mac terminal: npm install rapydscript

Recieved this WARN message and a series of 304 http statuses:
npm WARN package.json [email protected] 'repositories' (plural) Not supported. Please pick one as the 'repository' field

npm http GET https://registry.npmjs.org/rapydscript
npm http 304 https://registry.npmjs.org/rapydscript
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/async
npm http 304 https://registry.npmjs.org/optimist
npm http 304 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/wordwrap
npm http 304 https://registry.npmjs.org/wordwrap
[email protected] node_modules/rapydscript
├── [email protected]
└── [email protected] ([email protected])

A cursory search shows some others worked around this: npm/npm#3741

My best,
Jay

iterating through hash keys

Python allows the following syntax:

for key in hash:
    print key

In RapydScript this behavior is undefined, and in a typical JavaScript-way, it usually does what you don't want, while pretending to have completed successfully. While the following is possible:

for key in Object.keys(hash):
    print key

I think allowing the first syntax as well is a good way to prevent the devs from shooting themselves in the foot. I could do so by introducing a _$rapyd$_Iterable() function and assigning its output to _$rapyd$_Iter rather than the original object.

Unpack tuple to multiple targets not supported

def kproperty(exports):
    exports.L2, exports.L1, exports.L0 = L2, L1, L0  # works

    exports.L2, exports.L1, exports.L0 = L2, L1, L0 = (2, 1, 0) # failed

which generates

function kproperty(exports) {
    var _$rapyd$_Unpack;
    _$rapyd$_Unpack = [L2, L1, L0];
    exports.L2 = _$rapyd$_Unpack[0];
    exports.L1 = _$rapyd$_Unpack[1];
    exports.L0 = _$rapyd$_Unpack[2];

    _$rapyd$_Unpack = [L2, _$rapyd$_Unpack = [2, 1, 0]; 
    L1 = _$rapyd$_Unpack[0];
    L0 = _$rapyd$_Unpack[1]];
    exports.L2 = _$rapyd$_Unpack[0];
    exports.L1 = _$rapyd$_Unpack[1];
    exports.L0 = _$rapyd$_Unpack[2];
}

Dict value cannot be in a new line

The following code failed to compile with an ERROR: Unexpected token error.

a = {"ke":
        "looooooong string"
    }

It seems that the value must be in the same line of the semicolon.

Python docstrings

I have found that some RapydScript code which I have not modified for a while no longer compiles. I eventually tracked the problem down to comments like this:

""" This is a Python docstring """
This throws an exception at parse.js line 578
TypeError: cannot read property 'length' of null

The problem seems to be having both triple quotes on the same line.

I am pretty sure that this problem has arisen relatively recently, otherwise I would have already been aware of it.

npm install error

Attempted both of the following installation methods:

  1. sudo npm install rapydscript -g
  2. git clone git://github.com/atsepkov/RapydScript.git
    cd RapydScript
    npm link

Received the same error both times:

"""
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'link' ]
2 info using [email protected]
3 info using [email protected]
4 verbose linkPkg /home/peter/RapydScript
5 verbose read json /home/peter/RapydScript/package.json
6 error Error: invalid version: 0.2.02
6 error at validVersion (/usr/lib/nodejs/read-package-json/read-json.js:573:40)
6 error at final (/usr/lib/nodejs/read-package-json/read-json.js:323:23)
6 error at /usr/lib/nodejs/read-package-json/read-json.js:139:33
6 error at cb (/usr/lib/nodejs/slide/lib/async-map.js:48:11)
6 error at /usr/lib/nodejs/read-package-json/read-json.js:316:40
6 error at fs.js:268:14
6 error at /usr/lib/nodejs/graceful-fs/graceful-fs.js:103:5
6 error at Object.oncomplete (fs.js:107:15)
7 error If you need help, you may report this log at:
7 error http://bugs.debian.org/npm
7 error or use
7 error reportbug --attach /home/peter/RapydScript/npm-debug.log npm
8 error System Linux 3.11.0-12-generic
9 error command "/usr/bin/nodejs" "/usr/bin/npm" "link"
10 error cwd /home/peter/RapydScript
11 error node -v v0.10.15
12 error npm -v 1.2.18
13 verbose exit [ 1, true ]
"""

Seems like an npm error but other packages install cleanly, including rapydscripts dependencies: optimist and async.

Seems like the version labelling is wrong somewhere as it's appending an additional '0' onto 0.2.2 to become 0.2.02

Tried installing legacy versions and the same error occurs. For example, attempting to install version 0.2.1 will return an invalid version error of 0.2.01.

This is on a Linux machine running Mint.

Extended slice notation missing

as described in Python 2.3 docs (still correct despite being 11 years old now).

Python2:

>>> print range(1,10)[::2]
[1, 3, 5, 7, 9]

Python3:

>>> print(range(1, 10)[::2])
range(1, 10, 2) # not helpful, let's force things. Also not expecting Rapydscript to have Python's iterator semantics.
>>> print(list(range(1, 10)[::2]))
[1, 3, 5, 7, 9]

Rapydscript console (on rapydscript.com/try-it/):

print(range(10)[::2])
ERROR: Unexpected token: punc «:». Line 1, column 17.

And yes, I know that range() takes a third parameter. But extended slicing is an operation available at least on regular Python lists, where it still fails.

Rapydscript console:

print([1,2,3,4,5][::2])
ERROR: Unexpected token: punc «:». Line 1, column 19.

Javascript V8 engine has no list method 'insert'

as is in the title

list.insert work fine in web based javascript environment but not work in V8 engine like node.js.

consider the following code
l = [1,2,3]
[ 1, 2, 3 ]
l.insert(0,'hh')
would produce TypeError: Object 1,2,3 has no method 'insert' in node.js

temporary solution:

def insert(lst,index,value):
    # Node.js has no list method 'insert'
    try:
        if window:
            if lst:
                lst.insert(index,value)
                return lst
    except:
        value = [value]
        l = lst[0:index]
        r = lst[index:]
        l = l.concat(value)
        return l.concat(r)

add support for reverse ranges

The following works fine
a = [1 to 5]

The following does not:
a = [5 to 1]

I'll tweak the compiler to generate reverse range for the shortcut at the bottom

RapydScript has same problems Javascript has

RapydScript doesn't encapsulate and validate the source code properly.

# RapydScript
a = [1, 2]
b = [3, 4]
alert(a + b) # As a python programmer I expect it to be [1, 2, 3, 4]
"1" == True # expected to be False
// Converted to Javascript
a = [1, 2]
b = [3, 4]
alert(a + b) // but unfortunately the converted code returns a string ie "1,23,4"
"1" == true // but unfortunately it is still True

I really love the clean syntax of RapydScript, however, it is not even a strongly typed language as Python.

I wish Python and RapydScript both to be statically typed languages so that it is possible to help IDEs to catch a lot of errors before the run-time.

Input must end in newline

If your editor doesn't automatically end a file with a new line, you might get an error like this, its really confusing.... We got this on kate with append new line set to false

WARN: ERROR: Unexpected token: eof «undefined» [test.rpy:15,2]

/home/aaronc/other_projects/RapydScript/lib/parse.js:122
    throw new JS_Parse_Error(message, line, col, pos);
          ^
Error
    at new JS_Parse_Error     (/home/aaronc/other_projects/RapydScript/lib/parse.js:110:18)
    at js_error (/home/aaronc/other_projects/RapydScript/lib/parse.js:122:11)
    at croak (/home/aaronc/other_projects/RapydScript/lib/parse.js:707:9)
    at token_error (/home/aaronc/other_projects/RapydScript/lib/parse.js:710:9)
    at unexpected (/home/aaronc/other_projects/RapydScript/lib/parse.js:716:9)
    at block_ (/home/aaronc/other_projects/RapydScript/lib/parse.js:1523:21)
    at /home/aaronc/other_projects/RapydScript/lib/parse.js:1453:21
    at /home/aaronc/other_projects/RapydScript/lib/parse.js:1460:15
    at /home/aaronc/other_projects/RapydScript/lib/parse.js:938:24
    at /home/aaronc/other_projects/RapydScript/lib/parse.js:747:20

add existential 'operator'

CoffeeScript has the concept of existential operator: a?, which compiles to the following:

typeof a !== "undefined" && a !== null

Until recently, RapydScript used == for equality and as a result the need for such check was somewhat rare. With === equality that the compiler now uses, such operator would be useful. Already I find myself checking against both null and undefined more and more often, this annoyance would further aggravate those coming from Python background and unfamiliar with JS quirks. Here are a couple alternatives I was thinking about for handling such an operator:

if exists(a):
    ...

Pros:
concise, readable and doesn't introduce funky operators that may be unfamiliar with Python devs
perl already has the same function, used for the same purpose (but typically for testing hash keys)
Cons:
Python devs may not be aware of the need for exists() test

if a is None:
    ...

Pros:
already widely used in Python code, optimizer could then take care of this compilation for us
is operator is currently useless, as it's identical to ==
Cons:
there may be legitimate reasons for checking against null and not undefined, which this would break
in Python, is is more strict than ==, this check would actually be less strict than == (however, JS === is already more like is in Python rather than == for object types)

for loop off by 1

With this code:

for n in range(5):
    print (n)

print ('n should be 4:', n)

I get this output:

0
1
2
3
4
"n should be 4:",5 

Rapydscript generates this code:

for (n = 0; n < 5; n++) {
    _$rapyd$_print(n);
}
_$rapyd$_print("n should be 4:", n);

It does not matter if I "include stdlib" or not.

But, everything works as expected if I do this:

for i, n in enumerate(range(5)):
    print (i, n)

print ('n should be 4:', n)

In this version, Rapydscript uses the stdlib range() function

Properties ("Getters and Setters")

Python Properties and JavaScript Getters and Setters have much in common: They mimic attribute access when in reality a getter and setter method is called. Just the Syntax is different. I made a little example to see how far this works with RapydScript:

class Element:
    def __init__(self, tag, attrib):
        self._children = []
        # variant 1: this is be the javascript way of declaring getters
        # see http://stackoverflow.com/a/813332/852994
        get length() = def(self):
            return len(self._children)

    # variant 2:  pythons native property-getters and -setters would make
    # sense to be translated to js-getter and -setters, see variant 1
    @property
    def length(self):
        return len(self._children)

    # varuant 3: while python has obj.__len__(), javascript has obj.length
    # thus it would make sense to replace the following by variant 2
    def __len__(self):
        return len(self._children)

Sadly, none of those variants above is properly translated with the current version of RapydScript:

Element = function(tag, attrib){
    var self = this;
    self._children = [];
    get;
    length() = function(self) {
        return len(self._children);
    };
};
Element.prototype.length = function(){
    var self = this;
    return len(self._children);
};
Element.prototype.__len__ = function(){
    var self = this;
    return len(self._children);
};

What I would wish for would be, that property decorators translate into javascript getters and setters and that magic functions like str(), len() etc. would be mapped to their javascript counterparts (in case of str() that would be toString()) maybe leveraging those properties thus making it easier to reuse and mix client code and backend code.

Thanks a lot for developing RapydScript btw.!

Easier override of regular js functions (namespacing python functions)

This is an enhancement proposal.

I would like to use str.split() in my RapydScript code but it collides with String.split (the js equivalent) which otherwise doesn't behave in the same way. This makes it difficult to overload.

Therefore, I would like to ask if it would be possible in a future version to:

  1. Export python functions in their own namespace to JS (e.g. String.py.split would be the python splot function)
  2. automatically use String.py.split from all RapydScript code (e.g. hold an array of all overloaded/available functions in the RapydScript parser and then use them accordingly

I know that this might be not entirely in the spirit of keeping RapydScript as a light layer on top of js. I think, however, it does not add any "magic" and is quite transparent.

It might also be cool for operator overloading where you could check during the parsing if the object contains and add method etc.

Probably it would need a two-stage parsing process to be successful?

Best,

Wolf

Support for array declaration via *size

Python allows the following:

a = [None]*10

JS does not, adding it to RS could be useful.

Similarly, in case where the multiplier is a variable, one could let the browser know this ahead of time, to allow its optimization to kick in:

>>> a = [None]*n

var a = []; a.length = n;
for (var _ = 0; _ < a.length; _++) a[_] = None;

Tuple Notation

Hi,

In RapydScript, array notation is already exists as [], dict notation is also exists as {}, but tuple notation is not useable as (). I am currently developing some of the data structures including tuples, and I can not find where should I change in the code. I look parse.pyj but didn't get any result.

Can any body show me where should add this () tokens or can any body help me about developing this syntax?

The auto 'new' feature does not work across multi-level imports

Suppose we have a file test_c.pyj, which defines a class 'C', and test_b.pyj which imports test_c and defines a class 'B', and test.pyj that imports test_b and defines a class A, then in test.pyj, a = A() and b = B() works as expected (the 'new' keyword is automatically inserted before A() and B()), but c = C() does not.

Syntax highlighting for TextMate

Hi is it possible to get syntax highlighting in a Textmate bundle for Rapydscript? I really want to use Rapydscript but syntax highlighting is important, and I wanna use it in PyCharm and IntelliJ which are compatible with Textmate bundles.

print doesn't work in node

to avoid breaking in older versions of IE, print() checks for window, which doesn't exist in node. Seeing how we're dropping support for old IE browsers soon anyway, I will go ahead and remove that check.

WARN: ERROR: Invalid syntax: 1e [math.pyj:92,25]

New self-hosted version left out support for this:

if Math.abs(x) < 1e-5:

In src/lib/math.pyj

Test case is a one-liner:

import math

As a temporary workaround, I changed this to 0.0001 in my local copy, rather than try to patch the parser.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.