-
Notifications
You must be signed in to change notification settings - Fork 50
JavaScript Unicode Literate Output
The command line option --literate-unicode
enables unicode variable names in the output javascript. To check if the unicode characters are valid in javascript, go to: https://mothereff.in/js-variables
Note that mini-macros can use any unicode characters, and the option --literate-unicode
is not required, this is because the mini-macro name is replaced by the macro definition at compile time.
- https://github.com/rusthon/Rusthon/blob/master/examples/hello_literate_unicode.md
This is a spec that makes some suggestions how to implement a unicode language that is output from a transpiler into JavaScript.
Some of the spec comes from a Python-to-JavaScript perspective, other parts are generic. The spec is intended to be implemented by a transpiler, and not hand written by people. The intention is to have a unicode based language that is easy for people to read, with as little eye strain as possible. Note that, by "language" we are talking about variable and function names, not actual syntax because that remains JavaScript.
In the development of the spec many fonts were tried, and viewed in the browser and different text editors, the primary font that is clear and distinct was found to be: Mathematical Bold Italic. This font clearly stands out from regular text, so the user is quickly able to see their own code from the builtin functions of the language.
Another font we recommend for special cases is: Mathematical Double Struck. It can be used to signal the user that the item it refers to is in some way hidden or not to be used directly. If the transpiler allows end users to define their own unicode based variables and functions, the end user should not used double-struck fonts, to avoid any conflicts with internal use.
When translating a for loop that iterates over items in an array, for item in somearray:
,
an index variable needs to be generated. To improve readability of the JavaScript output,
the generated index variable can be named 𝓷
. That is the mathematical bold script small n, U+1D4F7.
If there are nested for loops, then a unique index must be generated for each one, in these cases 𝓷
can be followed by a number, 𝓷1
.
Note that while it would be more readable to use subscript numbers: ₀₁₂₃₄₅₆₇₈₉
. They are not in the valid unicode range.
If the transpiler also needs to generate an iterator name for the loop, it can prefix the name with 𝕚𝕥𝕖𝕣
Example translation for this python input: for k in mydict: pass
var 𝕚𝕥𝕖𝕣mydict = mydict;
// some runtime magic here the transpiler may inject to reassign `𝕚𝕥𝕖𝕣mydict` to an array of its keys
for (var 𝓷 = 0; 𝓷 < 𝕚𝕥𝕖𝕣mydict.length; 𝓷++) {
var k = 𝕚𝕥𝕖𝕣idict[ 𝓷 ];
}
Python has a whole set of builtin functions, but often these names are too short;
while that makes it quick to type, reading it becomes harder.
In addition, the output code may be read by other programmers, who know JavaScript
but may not know the Python API and builtins, for these users,
plain English names are going to be much easier to understand.
This is not an absolute rule, for example dict
and dir
look ok with their short-handed names.
The Python builtin function getattr( OBJECT, NAME )
should be transpiled to:
𝑮𝒆𝒕𝑨𝒕𝒕𝒓𝒊𝒃𝒖𝒕𝒆( OBJECT, NAME )
.
The Python builtin function setattr( OBJECT, NAME, VALUE )
should be transpiled to:
𝑺𝒆𝒕𝑨𝒕𝒕𝒓𝒊𝒃𝒖𝒕𝒆( OBJECT, NAME, VALUE )
.
The Python builtin function int( NUMBER )
should be transpiled to:
𝑰𝒏𝒕𝒆𝒈𝒆𝒓( NUMBER )
.
The Python builtin function float( NUMBER )
should be transpiled to:
𝑭𝒍𝒐𝒂𝒕( NUMBER )
.
The Python builtin function str( OBJECT )
should be transpiled to:
𝑺𝒕𝒓𝒊𝒏𝒈( OBJECT )
.
The Python builtin class dict( OBJECT )
should be transpiled to:
𝑫𝒊𝒄𝒕( OBJECT )
. Note: in this case we recommend keeping the short-hand name.
The Python builtin class list( OBJECT )
should be transpiled to:
𝑳𝒊𝒔𝒕( OBJECT )
.
The Python builtin class set( OBJECT )
should be transpiled to:
𝑺𝒆𝒕( OBJECT )
.
The Python builtin function len( LIST )
should be transpiled to:
𝑳𝒆𝒏𝒈𝒕𝒉( LIST )
.
The Python builtin function isinstance( LIST )
should be transpiled to:
𝑰𝒔𝑰𝒏𝒔𝒕𝒂𝒏𝒄𝒆( LIST )
.
The Python builtin function sum( LIST )
should be transpiled to:
𝑳𝒊𝒔𝒕𝑺𝒖𝒎( LIST )
.
note: while it would be more mathmatically correct to use sigma ∑
,
this is currently not in the valid unicode range for javascript variables.
But wait, U+1D6F4, 𝛴
is in the valid unicode range, so another option is:
𝛴( LIST )
However the problem with this is it inconsistent with the rest of the naming
convention here, and most of the math symbols are not in the unicode range
allowed for js variable names.
The Python builtin function map( FUNCTION, LIST )
should be transpiled to:
𝑳𝒊𝒔𝒕𝑴𝒂𝒑( FUNCTION, LIST )
The Python builtin function filter( FUNCTION, LIST )
should be transpiled to:
𝑳𝒊𝒔𝒕𝑭𝒊𝒍𝒕𝒆𝒓( FUNCTION, LIST )
The Python builtin function min( LIST )
should be transpiled to:
𝑳𝒊𝒔𝒕𝑴𝒊𝒏( LIST )
The Python builtin function max( LIST )
should be transpiled to:
𝑳𝒊𝒔𝒕𝑴𝒂𝒙( LIST )
The Python builtin function abs( NUMBER )
should be transpiled to:
𝑨𝒃𝒔𝒐𝒍𝒖𝒕𝒆( NUMBER )
The Python builtin function chr( NUMBER )
should be transpiled to:
𝑪𝒉𝒂𝒓𝒂𝒄𝒕𝒆𝒓( NUMBER )
The Python builtin function org( CHAR )
should be transpiled to:
𝑶𝒓𝒅𝒊𝒏𝒂𝒍( CHAR )
A Python to JavaScript transpiler will likely need to have its own set of internal helper functions that are not part of the regular Python standard, the following is suggestions for some of these basic helpers and their names.
JavaScript contains Array, and several other types that are Array-like, but are actually different types of objects, like: NodeList, FileList, DOMStringList, and others. The function, 𝑰𝒔𝑨𝒓𝒓𝒂𝒚( OBJECT )
, should be able to detect those types and return true if the argument is Array-like. Below is an example implementation.
__dom_array_types__ = []
if typeof(NodeList) == 'function': ## NodeList is only available in browsers
## minimal dom array types common to allow browsers ##
__dom_array_types__ = [ NodeList, FileList, DOMStringList, HTMLCollection, SVGNumberList, SVGTransformList]
## extra dom array types ##
if typeof(DataTransferItemList) == 'function': ## missing in NodeWebkit
__dom_array_types__.push( DataTransferItemList )
if typeof(HTMLAllCollection) == 'function': ## missing in Firefox
__dom_array_types__.push( HTMLAllCollection )
if typeof(SVGElementInstanceList) == 'function':## missing in Firefox
__dom_array_types__.push( SVGElementInstanceList )
if typeof(ClientRectList) == 'function': ## missing in Firefox-trunk
__dom_array_types__.push( ClientRectList )
def 𝑰𝒔𝑨𝒓𝒓𝒂𝒚( ob ):
if __dom_array_types__.length > 0:
for t in __dom_array_types__:
if instanceof(ob, t):
return True
return False
JavaScript includes typed arrays, however not all browsers support every type of typed array, that is why we need this helper function. Below is an example implementation.
def 𝑰𝒔𝑻𝒚𝒑𝒆𝒅𝑨𝒓𝒓𝒂𝒚( ob ):
if instanceof( ob, Int16Array ) or instanceof( ob, Uint16Array ):
return True
elif instanceof( ob, Int32Array ) or instanceof( ob, Uint32Array ):
return True
elif instanceof( ob, Float32Array ) or instanceof( ob, Float64Array ):
return True
else:
return False