GlowScript that doesn't work in standard Python

80 views
Skip to first unread message

Daniel Schroeder

unread,
Feb 7, 2018, 11:45:32 PM2/7/18
to Glowscript Users
I've already stumbled upon at least two things you can do in GlowScript that are forbidden in standard Python (and that are unrelated to all of the VPython features of GlowScript). Today one of my students pointed out a third such feature. So I've put them into a little example program:


Are there other examples that I should add to this little list?

Dan


Bruce Sherwood

unread,
Feb 8, 2018, 10:22:28 AM2/8/18
to Glowscript Users
In the README at https://github.com/kovidgoyal/rapydscript-ng are described various non-standard capabilities of the RapydScript-NG Python-to-JavaScript transpiler. The most interesting difference is that one can execute jquery code in a Python program. 

There is a specific section on "Gotchas", and the most serious one is that 1+'1', which is an error in Python, yields '11' due to the nature of the underlying JavaScrpt.

The next statement in the Gotchas says that [1]+[1] returns a string, but in fact it does correctly yield [1,1]. I think this is a documention error, which I'll report.

The statement after that says, "RapydScript does not implement operator overloading, as method calls in JavaScript are very slow compared to raw operators." GlowScript does implement operator overloading, albeit in just some special cases, most notably vectors, and my own measurements indicate that the overhead is surprisingly small, about 30%. But maybe for RapydScript to implement operator overloading in general would be expensive in execution time.

Because I have to do a lot of preprocessing and postprocessing of VPython code, I believe I could give an error for "!a"; just look for "!" not followed by "=". Also, I currently have to track the names of and calls of functions in order to setup the Streamline machine that permits infinite loops and pauses, so I think I could catch a call to a function that has not yet been defined. I don't think I can do anything about the curious JavaScript scheme of x = [ ]; x[5] = 42, as that would require expensive run-time checks, though I should make measurements. Also, it might be prohibitively costly to catch 1+'1'.

I do see some value in doing this. For example, a colleague prefers to check student GlowScript programs by running them in Jupyter 7, but then there are errors that didn't show up in GlowScript (and didn't affect the correct execution at glowscript.org). So keep those gotchas coming, and I'll continue to look into ways to treat them as errors. If it does turn out to be feasible, it will require increasing the version number, since otherwise existing program might fail under the stricter regime.

A general comment about RapydScript-NG: There are many many projects aimed at transpiling Python to JavaScript, however with the exception of RapydScript, they are VERY slow. For example, in December 2016 a widely mentioned transpiler named Brython was (at that time) 15 times slower than Python, whereas GlowScript VPython was 5 times faster than Python, a factor of 75 in speed! The key is that Brython attempts to emulate true Python exactly, whereas RapydScript aspires to do as good a job as possible but without sacrificing speed. One of the consequences of this approach is that RapydScript is a rather thin wrapper around JavaScript.

Bruce

Daniel Schroeder

unread,
Feb 8, 2018, 10:44:24 AM2/8/18
to Glowscript Users
Come to think of it, my students have also discovered that they can add numbers to strings.  I had forgotten that Python doesn't allow this.  I've now included it in my example program.

To be clear, these differences don't bother me much and I'm not asking anyone to fix them.  I just think it's important to document them somewhere, so students won't be blindsided when they switch from GlowScript to standard Python.

Dan

Bruce Sherwood

unread,
Feb 8, 2018, 10:46:12 AM2/8/18
to Glowscript Users
Agreed and understood. But as I said, there are other reasons for wanting to catch these differences.

Bruce

Bruce Sherwood

unread,
Feb 8, 2018, 11:47:01 AM2/8/18
to Glowscript Users
My mistake about "The next statement in the Gotchas says that [1]+[1] returns a string, but in fact it does correctly yield [1,1]. I think this is a documentation error, which I'll report." It works because of something that I do.

Bruce

dbor...@willamette.edu

unread,
Feb 14, 2018, 12:49:36 AM2/14/18
to Glowscript Users
Not so much forbidden, but 

list = ["dog","cow","cat"]
print(list)

gives different outputs in Glowscript and in Python.

In Glowscript, this gives

>> [dog, cow, cat]

In Python, this gives

>> ['dog', 'cow', 'cat']

Note the extra single quotes. I could imagine this would break some hypothetical code that was parsing strings or something.

Cheers, 

Daniel

Bruce Sherwood

unread,
Feb 14, 2018, 9:51:46 AM2/14/18
to Glowscript Users
Thanks for the observation. It's only an issue of the display. The GlowScript library has its own print function in order to do such things as display a vector in the form <x,y,z>. The mistake in that function is that when it constructs the display of a list it needs to test whether an element is a string, and, if so, display quote marks around instead of simply displaying the contents of the string.

Note that the true Python print() function does treat strings differently if inside or outside a list, something that I hadn't previously noticed:

a = 'hello'
print(a) => hello, with no quote marks

b = ['hello']
print(b) => ['hello']

I'll fix this.

Bruce

Bruce Sherwood

unread,
Feb 14, 2018, 3:00:28 PM2/14/18
to Glowscript Users
Okay, it's now the case that 

list = ["dog","cow","cat"]
print(list)

displays  ['dog', 'cow', 'cat']

Bruce

Daniel Schroeder

unread,
Mar 17, 2018, 1:30:08 PM3/17/18
to glowscri...@googlegroups.com
Here's another one. GlowScript lets you use expressions that don't always result in integers as list indices, and does the right thing when the result is an integer:

myList = ["Item0", "Item1", "Item2"]
print(myList[2/2])

In GlowScript this prints "Item1", but in standard Python it generates an error:

TypeError: list indices must be integers or slices, not float

Even myList[3/2] is merely "undefined" in GlowScript, rather than something the interpreter won't let you do.

Bruce Sherwood

unread,
Mar 17, 2018, 1:53:55 PM3/17/18
to Glowscript Users
Actually, it's a little more complicated than that. In Python 2.x (but not Python 3.x) myList[2/2] treats this as myList[1] because without "from __future__ import division" division is integer division. In Python 3.x division is floating division, and integer division is available as 2//2 (which is also available in Python 2.7).

Bruce

Daniel Schroeder

unread,
Mar 17, 2018, 2:26:14 PM3/17/18
to Glowscript Users
Sure, but the issue isn't specific to division. In GlowScript you can also say myList[sqrt(4)] and even myList[4**0.5]. I'm wondering if the issue is even specific to list indices. Are there other situations that can come up in both GlowScript and standard Python where a number is syntactically required to be an integer?

Bruce Sherwood

unread,
Mar 17, 2018, 4:13:34 PM3/17/18
to Glowscript Users
The fundamental issue is that JavaScript (to which GlowScript VPython is transpiled) has a number class that includes both integers and floats. So if you specify the Nth element in a list, and N has no fractional part, JavaScript is happy.

There is even a blurring of numbers and strings:

s = 37.4+'hello'
print(s)  # displays the string "37.4hello"

Bruce

Sebastian Silva

unread,
Mar 17, 2018, 4:16:41 PM3/17/18
to glowscri...@googlegroups.com, Daniel Schroeder

Hi,

The thing to understand is that Glowscript ultimately runs under the browser Javascript engine instead of the standalone Python interpreter.

Therefore these discrepancies stem from differences between one and the other.

While Python has float, int (and long in 2.7), Javascript has only Number.

It becomes even more interesting with collections. Python has tuple, list and dictionary, but Javascript has Array and Object.

Glowscript does its best to map one to the other, while maintaining performance. Incompatibilities inevitably arise from cases where one abstraction doesn't match the other.

Regards,

Sebastian


On 17/03/18 13:26, Daniel Schroeder wrote:
Sure, but the issue isn't specific to division. In GlowScript you can also say myList[sqrt(4)] and even myList[4**0.5]. I'm wondering if the issue is even specific to list indices. Are there other situations that can come up in both GlowScript and standard Python where a number is syntactically required to be an integer?
--

---
You received this message because you are subscribed to the Google Groups "Glowscript Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glowscript-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Schroeder

unread,
Mar 17, 2018, 5:02:51 PM3/17/18
to Glowscript Users
Bruce: Yes, the automatic conversion of numbers to strings in such situations is something I documented in the sample program linked from the message at the beginning of this thread.

Sebastian: I'm aware that GlowScript Python is really JavaScript. What I don't really understand is what it means to say that "JavaScript has only Number". JavaScript array indices must be integers, right? Moreover, even standard Python allows you to say "x = 2; x+=0.5", so it freely converts integers to floats as needed. The difference is in how the two languages handle situations where an integer is needed and the interpreter can't tell in advance whether an expression will give an integer result.
Reply all
Reply to author
Forward
0 new messages