Difference between revisions of "Python"
(Created page with "Python is a popular scripting language that was first released in 1991. This article compares Python to MiniScript, and may be useful to people coming to MiniScript with a ba...") |
|||
(14 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Python is a popular scripting language that was first released in 1991. This article compares Python to MiniScript, and may be useful to people coming to MiniScript with a background in Python. | Python is a popular scripting language that was first released in 1991. This article compares Python to MiniScript, and may be useful to people coming to MiniScript with a background in Python. | ||
+ | |||
+ | For a side-by-side comparison on a collection of short programs, see [https://miniscript.org/compare/python.html here]. | ||
== Similarities == | == Similarities == | ||
=== Data Types === | === Data Types === | ||
+ | |||
+ | MiniScript's six data types have direct analogs to common types in Python: | ||
+ | |||
+ | * '''Numbers''' in MiniScript are double-precision floating point numbers, equivalent to Python's <c>numbers.Real</c> (aka <c>float</c>) data type. Note that in MiniScript, False and True are represented directly by the numbers 0 and 1; there is no separate <c>bool</c> type. | ||
+ | |||
+ | * '''Strings''' in both languages are an immutable sequence of Unicode code points. String literals in both languages can be enclosed in double-quotes; MiniScript does not have the optional single-quote or triple-quote syntax. While Python uses backslash-escaping to include a quotation mark within a literal, in MiniScript you just write the quotation mark twice, as in SQL. | ||
+ | |||
+ | * '''Lists''' in both languages are a mutable sequence of arbitrary values; a list literal uses square brackets surrounding comma-delimited values (see List Syntax, below). Note that MiniScript does not have a <c>tuple</c> type, and uses a list in situations where Python might use a tuple. | ||
+ | |||
+ | * '''Maps''' in both languages are mutable, unordered set of key-value pairs, with the same literal syntax (see Map Syntax and Object-Oriented Programming, below). | ||
+ | |||
+ | * '''Function objects''' in both languages are similar: first-class, callable objects. However functions in MiniScript have no attributes, and the syntax for defining functions is somewhat different. | ||
+ | |||
+ | * '''<c>None</c>''' in Python is called '''<c>null</c>''' in MiniScript — a special datatype in both languages, representing a null reference. | ||
=== List Syntax === | === List Syntax === | ||
− | === Map Syntax === | + | The syntax for list literals is the same in Python and MiniScript: a series of arbitrary values, separated by commas and surrounded by square brackets. |
+ | |||
+ | <ms>myList = ["apple", "banana", "cherry", "date"]</ms> | ||
+ | |||
+ | Index and slice syntax is also the same in both, except that MiniScript slicing supports only two parameters; it does not support the third (IndexJump) parameter. | ||
+ | |||
+ | <ms>myList[0] // "apple" | ||
+ | myList[:2] // ["apple", "banana"] | ||
+ | myList[-3:] // ["banana", "cherry", "date"] | ||
+ | myList[1:-1] // ["banana", "cherry"] | ||
+ | myList[:] // independent copy of ["apple", "banana", "cherry", "date"]</ms> | ||
+ | |||
+ | Unlike Python, you cannot assign to a slice; you can only assign to a single index. | ||
+ | |||
+ | <ms>myList[1] = "orange" // myList is now: ["apple", "orange", "cherry", "date"] | ||
+ | myList[1:3] = ["lemon"] // DOES NOT WORK</ms> | ||
+ | |||
+ | Like Python, indexing and slicing in MiniScript also applies to strings (excluding assignment since strings in both languages are immutable). | ||
+ | |||
+ | === Map (Dictionary) Syntax === | ||
+ | |||
+ | The equivalent of a Python ''dict'' is called a ''map'' in MiniScript. The syntax for such literals, and indexing into them, is the same in Python and MiniScript: | ||
+ | |||
+ | <ms>m = {"one":1, "two":2, "three":3} | ||
+ | print m["two"] // 2 | ||
+ | m["pi"] = 3.14</ms> | ||
+ | |||
+ | Unlike Python, in MiniScript when a key in a map happens to also be a valid literal, it can be accessed via [[dot syntax]]. | ||
+ | |||
+ | <ms>print m.two // 2 | ||
+ | m.pi = 3.14157</ms> | ||
+ | |||
+ | MiniScript does not have a concept of "attributes" as something separate from key/value pairs in a map. | ||
=== Variable Scope === | === Variable Scope === | ||
+ | |||
+ | Variables in both Python and MiniScript are local by default. There are some subtle differences, however: in Python, an inner function can implicitly access the variables of an outer function, but ''can't'' implicitly access global variables, while in MiniScript, any function can implicitly read values from both the outer context and the global context. To update a global variable, where Python uses a special <c>global</c> statement, MiniScript uses a <c>globals</c> prefix in a manner similar to using <c>self</c> to access object data. | ||
+ | |||
+ | <ms> | ||
+ | x = 0 | ||
+ | count = function | ||
+ | globals.x = x + 1 | ||
+ | print "The new count is: " + x | ||
+ | end function | ||
+ | |||
+ | count // The new count is: 1 | ||
+ | count // The new count is: 2 | ||
+ | count // The new count is: 3 | ||
+ | </ms> | ||
=== Object-Oriented Programming === | === Object-Oriented Programming === | ||
+ | |||
+ | Both MiniScript and Python support object-oriented programming, with some similarities and some differences. MiniScript uses '''prototype-based inheritance''', where the difference between "class" and "instance" is mainly in the mind of the programmer. Classes/instances are just maps, with the inheritance chain stored in a special <c>__isa</c> entry that is automatically set by the [[new]] operator. | ||
+ | |||
+ | Similarities between MiniScript and Python: | ||
+ | * inheritance and polymorphism | ||
+ | * use of [[self]] and [[super]] | ||
+ | |||
+ | Differences in MiniScript, as compared to Python: | ||
+ | * prototype-based inheritance built on classes | ||
+ | * use of [[new]] to subclass or create an instance | ||
+ | * no constructors | ||
+ | * no operator overloading or other magic methods | ||
+ | |||
+ | This MiniScript example illustrates some of these similarities and differences: | ||
+ | |||
+ | <ms>Person = {} // any empty map can be considered a class | ||
+ | Person.init = function(name, age) // not a magic method; just an ordinary method | ||
+ | self.name = name // note use of self (an implicit parameter) | ||
+ | self.age = age | ||
+ | end function | ||
+ | |||
+ | Person.sayHello = function | ||
+ | print "Hello world!" | ||
+ | end function | ||
+ | |||
+ | Person.sayName = function | ||
+ | print "My name is " + self.name + "." | ||
+ | end function | ||
+ | |||
+ | CoolPerson = new Person // creating a "subclass" of Person | ||
+ | CoolPerson.sayHello = function // overriding a function | ||
+ | print "How you doin'?" | ||
+ | end function | ||
+ | |||
+ | Joey = new CoolPerson // creating an "instance" of CoolPerson | ||
+ | Joey.init "Joey", 28 | ||
+ | Joey.sayHello // prints: How you doin'? | ||
+ | Joey.sayName // prints: My name is Joey.</ms> | ||
== Differences == | == Differences == | ||
Line 39: | Line 139: | ||
| 69 | | 69 | ||
| 53 | | 53 | ||
+ | |} | ||
+ | |||
+ | === Block Syntax === | ||
+ | |||
+ | The most obvious difference between Python and MiniScript is in block syntax. While Python defines blocks by ending the opening line with a colon, and indenting the body of the block, MiniScript uses keyword pairs like <c>if</c>/<c>end if</c>, <c>for</c>/<c>end for</c>, and <c>function</c>/<c>end function</c> (more similar to Visual Basic). Indentation in MiniScript is strictly cosmetic, and is ignored by the compiler; and tools can automatically standardize or re-indent based on the keywords. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Python | ||
+ | ! MiniScript | ||
+ | |- | ||
+ | | <pre>def myfunc(): | ||
+ | for i in range(1, 11): | ||
+ | if i == 9: | ||
+ | print("Almost done...") | ||
+ | else: | ||
+ | print(i) | ||
+ | |||
+ | myfunc()</pre> | ||
+ | | <ms>myFunc = function | ||
+ | for i in range(1, 10) | ||
+ | if i == 9 then | ||
+ | print "Almost done..." | ||
+ | else | ||
+ | print i | ||
+ | end if | ||
+ | end for | ||
+ | end function | ||
+ | |||
+ | myFunc</ms> | ||
|} | |} | ||
Line 53: | Line 183: | ||
x = random.uniform(0,1) | x = random.uniform(0,1) | ||
print(x)</pre> | print(x)</pre> | ||
− | | < | + | | <ms>x = rnd |
− | print x</ | + | print x</ms> |
|} | |} | ||
+ | === Magic Methods and Attributes === | ||
− | + | Python uses a large number of "magic" (aka "dunder") methods and attributes which have special meaning to the interpreter. These support things like operator overloading (<c>__add__</c>, <c>__ne__</c>, etc.), class support (<c>__class__</c>, <c>__subclasshook__</c>), and documentation (<c>__doc__</c>). By implementing these methods or assigning to these attributes, you can substantially change the way instances of a class behave. | |
+ | |||
+ | MiniScript has no such magic methods or attributes, with the exception of the <c>__isa</c> key used to track inheritance in maps. <c>__isa</c> is automatically set by [[new]] and used by the [[isa]] operator, so in most cases user code should not ever need to touch it. | ||
− | + | MiniScript does not support any form of operator overloading, or hooks to intercept other aspects of object behavior; objects always behave the same way. | |
=== import === | === import === | ||
+ | |||
+ | While not part of the core language, several MiniScript environments (including [[Mini Micro]], [[Soda]], [[command-line MiniScript]], and [[Farmtronics]]) support an [[import]] command. However the semantics are a bit different from Python. | ||
+ | |||
+ | In MiniScript, the module name must be a string (usually, a string literal). The [[import]] command searches for a corresponding script file, runs it in its own call context, and binds the result (as a map) to an identifier of the same name in the calling context. | ||
+ | |||
+ | <ms>import "mathUtil" | ||
+ | print mathUtil.dice(3,6) // rolls 3d6 and prints the result</ms> | ||
+ | |||
+ | Note that [[import]] always runs the code in the imported module, even if it was run before. See the Usage Notes under [[import]] for an <c>ensureImport</c> function that may be helpful to ensure a module is imported only once. | ||
+ | |||
+ | MiniScript does not support the ''from'' syntax (e.g. Python's <c>from math import pi</c> or <c>from math import *</c>). | ||
=== range function === | === range function === | ||
+ | |||
+ | The very common built-in function <c>range</c> in both languages takes up to three arguments: ''start'', ''stop'', and ''step''. But there are a few differences to note: | ||
+ | |||
+ | * In Python, the ''stop'' value is not included in the resulting sequence, while in MiniScript it is (i.e., it is an inclusive bound). | ||
+ | * In Python, if ''stop'' is less than ''start'', the result is an empty list unless you also specify a negative ''step''. In MiniScript, if ''step'' is omitted in such a case, it defaults to -1 (and you get a list that counts down). | ||
+ | * In Python, if only one argument is given, it is considered ''stop'' and the resulting sequence counts from 0 up to (but not including) that value. In MiniScript, a single argument is ''start'' and the resulting sequence counts from that number down (or up) to 0. | ||
+ | * In Python, the result of <c>range</c> is a '''range''' object; in MiniScript it is an ordinary list. |
Latest revision as of 23:20, 19 September 2024
Python is a popular scripting language that was first released in 1991. This article compares Python to MiniScript, and may be useful to people coming to MiniScript with a background in Python.
For a side-by-side comparison on a collection of short programs, see here.
Contents
Similarities
Data Types
MiniScript's six data types have direct analogs to common types in Python:
- Numbers in MiniScript are double-precision floating point numbers, equivalent to Python's
numbers.Real
(akafloat
) data type. Note that in MiniScript, False and True are represented directly by the numbers 0 and 1; there is no separatebool
type.
- Strings in both languages are an immutable sequence of Unicode code points. String literals in both languages can be enclosed in double-quotes; MiniScript does not have the optional single-quote or triple-quote syntax. While Python uses backslash-escaping to include a quotation mark within a literal, in MiniScript you just write the quotation mark twice, as in SQL.
- Lists in both languages are a mutable sequence of arbitrary values; a list literal uses square brackets surrounding comma-delimited values (see List Syntax, below). Note that MiniScript does not have a
tuple
type, and uses a list in situations where Python might use a tuple.
- Maps in both languages are mutable, unordered set of key-value pairs, with the same literal syntax (see Map Syntax and Object-Oriented Programming, below).
- Function objects in both languages are similar: first-class, callable objects. However functions in MiniScript have no attributes, and the syntax for defining functions is somewhat different.
None
in Python is callednull
in MiniScript — a special datatype in both languages, representing a null reference.
List Syntax
The syntax for list literals is the same in Python and MiniScript: a series of arbitrary values, separated by commas and surrounded by square brackets.
myList = ["apple", "banana", "cherry", "date"]
Index and slice syntax is also the same in both, except that MiniScript slicing supports only two parameters; it does not support the third (IndexJump) parameter.
myList[0] // "apple"
myList[:2] // ["apple", "banana"]
myList[-3:] // ["banana", "cherry", "date"]
myList[1:-1] // ["banana", "cherry"]
myList[:] // independent copy of ["apple", "banana", "cherry", "date"]
Unlike Python, you cannot assign to a slice; you can only assign to a single index.
myList[1] = "orange" // myList is now: ["apple", "orange", "cherry", "date"]
myList[1:3] = ["lemon"] // DOES NOT WORK
Like Python, indexing and slicing in MiniScript also applies to strings (excluding assignment since strings in both languages are immutable).
Map (Dictionary) Syntax
The equivalent of a Python dict is called a map in MiniScript. The syntax for such literals, and indexing into them, is the same in Python and MiniScript:
m = {"one":1, "two":2, "three":3}
print m["two"] // 2
m["pi"] = 3.14
Unlike Python, in MiniScript when a key in a map happens to also be a valid literal, it can be accessed via dot syntax.
print m.two // 2
m.pi = 3.14157
MiniScript does not have a concept of "attributes" as something separate from key/value pairs in a map.
Variable Scope
Variables in both Python and MiniScript are local by default. There are some subtle differences, however: in Python, an inner function can implicitly access the variables of an outer function, but can't implicitly access global variables, while in MiniScript, any function can implicitly read values from both the outer context and the global context. To update a global variable, where Python uses a special global
statement, MiniScript uses a globals
prefix in a manner similar to using self
to access object data.
x = 0
count = function
globals.x = x + 1
print "The new count is: " + x
end function
count // The new count is: 1
count // The new count is: 2
count // The new count is: 3
Object-Oriented Programming
Both MiniScript and Python support object-oriented programming, with some similarities and some differences. MiniScript uses prototype-based inheritance, where the difference between "class" and "instance" is mainly in the mind of the programmer. Classes/instances are just maps, with the inheritance chain stored in a special __isa
entry that is automatically set by the new operator.
Similarities between MiniScript and Python:
Differences in MiniScript, as compared to Python:
- prototype-based inheritance built on classes
- use of new to subclass or create an instance
- no constructors
- no operator overloading or other magic methods
This MiniScript example illustrates some of these similarities and differences:
Person = {} // any empty map can be considered a class
Person.init = function(name, age) // not a magic method; just an ordinary method
self.name = name // note use of self (an implicit parameter)
self.age = age
end function
Person.sayHello = function
print "Hello world!"
end function
Person.sayName = function
print "My name is " + self.name + "."
end function
CoolPerson = new Person // creating a "subclass" of Person
CoolPerson.sayHello = function // overriding a function
print "How you doin'?"
end function
Joey = new CoolPerson // creating an "instance" of CoolPerson
Joey.init "Joey", 28
Joey.sayHello // prints: How you doin'?
Joey.sayName // prints: My name is Joey.
Differences
Language Scale
MiniScript is a considerably smaller language by any reasonable measure. For example, the following table compares Python and MiniScript on C/C++ source code lines, source code files, number of data types, and number of standard intrinsic functions, as of 2021 (source).
Python | MiniScript | |
---|---|---|
Source Lines | 661,775 | 13,752 |
Source Files | 718 | 46 |
Data Types | 34 | 6 |
Intrinsics | 69 | 53 |
Block Syntax
The most obvious difference between Python and MiniScript is in block syntax. While Python defines blocks by ending the opening line with a colon, and indenting the body of the block, MiniScript uses keyword pairs like if
/end if
, for
/end for
, and function
/end function
(more similar to Visual Basic). Indentation in MiniScript is strictly cosmetic, and is ignored by the compiler; and tools can automatically standardize or re-indent based on the keywords.
Python | MiniScript |
---|---|
def myfunc(): for i in range(1, 11): if i == 9: print("Almost done...") else: print(i) myfunc() |
myFunc = function
for i in range(1, 10)
if i == 9 then
print "Almost done..."
else
print i
end if
end for
end function
myFunc
|
Function Invocation
While functions in Python are always invoked by putting parentheses after a function reference, in MiniScript, such parentheses can be omitted when (1) the function call is the entire statement, or (2) there are no arguments.
Python | MiniScript |
---|---|
import random x = random.uniform(0,1) print(x) |
x = rnd
print x
|
Magic Methods and Attributes
Python uses a large number of "magic" (aka "dunder") methods and attributes which have special meaning to the interpreter. These support things like operator overloading (__add__
, __ne__
, etc.), class support (__class__
, __subclasshook__
), and documentation (__doc__
). By implementing these methods or assigning to these attributes, you can substantially change the way instances of a class behave.
MiniScript has no such magic methods or attributes, with the exception of the __isa
key used to track inheritance in maps. __isa
is automatically set by new and used by the isa operator, so in most cases user code should not ever need to touch it.
MiniScript does not support any form of operator overloading, or hooks to intercept other aspects of object behavior; objects always behave the same way.
import
While not part of the core language, several MiniScript environments (including Mini Micro, Soda, command-line MiniScript, and Farmtronics) support an import command. However the semantics are a bit different from Python.
In MiniScript, the module name must be a string (usually, a string literal). The import command searches for a corresponding script file, runs it in its own call context, and binds the result (as a map) to an identifier of the same name in the calling context.
import "mathUtil"
print mathUtil.dice(3,6) // rolls 3d6 and prints the result
Note that import always runs the code in the imported module, even if it was run before. See the Usage Notes under import for an ensureImport
function that may be helpful to ensure a module is imported only once.
MiniScript does not support the from syntax (e.g. Python's from math import pi
or from math import *
).
range function
The very common built-in function range
in both languages takes up to three arguments: start, stop, and step. But there are a few differences to note:
- In Python, the stop value is not included in the resulting sequence, while in MiniScript it is (i.e., it is an inclusive bound).
- In Python, if stop is less than start, the result is an empty list unless you also specify a negative step. In MiniScript, if step is omitted in such a case, it defaults to -1 (and you get a list that counts down).
- In Python, if only one argument is given, it is considered stop and the resulting sequence counts from 0 up to (but not including) that value. In MiniScript, a single argument is start and the resulting sequence counts from that number down (or up) to 0.
- In Python, the result of
range
is a range object; in MiniScript it is an ordinary list.