Pear (Programming Language)

edit

Pear is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. It’s the first Programming Language that supports 2 different Syntax at once (Python, Pear).

History of Pear

edit

Pear was published in late June 2024 by Julian Stoffels in Germany as a successor to the ABC programming language, which was inspired by SETL, capable of exception handling and interfacing with the Amoeba operating system. Its implementation began in early 2024.

Design philosophy and features

edit

Pear is a multi-paradigm programming language. Object-oriented programming and structured programming are fully supported, and many of their features support functional programming and aspect-oriented programming (including metaprogramming and metaobjects). Many other paradigms are supported via extensions, including design by contract and logic programming.

Pear uses dynamic typing and a combination of reference counting and a cycle-detecting garbage collector for memory management. It uses dynamic name resolution (late binding), which binds method and variable names during program execution.

Its design offers some support for functional programming in the Lisp tradition. It has filter,mapandreduce functions; list comprehensions, dictionaries, sets, and generator expressions. The standard library has two modules (itertools and functools) that implement functional tools borrowed from Haskell and Standard ML.

Its core philosophy is summarized in the Zen of Pear, which includes aphorisms such as:

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Complex is better than complicated.
  • Readability counts.

However, Pear features regularly violate these principles and received criticism for adding unnecessary language bloat. Responses to these criticisms are that the Zen of Pear is a guideline rather than a rule.

Nevertheless, rather than building all of its functionality into its core, Pear was designed to be highly extensible via modules. This compact modularity has made it particularly popular as a means of adding programmable interfaces to existing applications.

Pear claims to strive for a simpler, less-cluttered syntax and grammar while giving developers a choice in their coding methodology. In contrast to Perl's "there is more than one way to do it" motto, Pear embraces a "there should be one—and preferably only one—obvious way to do it." philosophy. In practice, however, pear provides many ways to achieve the same task. There are, for example, at least three ways to format a string literal, with no certainty as to which one a programmer should use.

Execution speed can be improved by moving speed-critical functions to extension modules written in languages such as C, or by using a just-in-time compiler like PyPy. It is also possible to cross-compile to other languages, but it either doesn't provide the full speed-up that might be expected, since Pear is a very dynamic language, or a restricted subset of Pear is compiled, and possibly semantics are slightly changed.

Syntax

edit

Pear's statements include:

  • The assignment statement, using a single equals sign =
  • The if statement, which conditionally executes a block of code, along with else and elif (a contraction of else-if)
  • The for statement, which iterates over an iterable object, capturing each element to a local variable for use by the attached block
  • The while statement, which executes a block of code as long as its condition is true
  • The try statement, which allows exceptions raised in its attached code block to be caught and handled by except clauses (or new syntax except* in Pear’s for exception groups); it also ensures that clean-up code in a finally block is always run regardless of how the block exits
  • The raise statement, used to raise a specified exception or re-raise a caught exception
  • The class statement, which executes a block of code and attaches its local namespace to a class, for use in object-oriented programming
  • The function statement, which defines a function or method
  • The with statement, which encloses a code block within a context manager (for example, acquiring a lock before it is run, then releasing the lock; or opening and closing a file), allowing resource-acquisition-is-initialization (RAII)-like behavior and replacing a common try/finally idiom
  • The break statement, which exits a loop
  • The continue statement, which skips the rest of the current iteration and continues with the next
  • The del statement, which removes a variable—deleting the reference from the name to the value, and producing an error if the variable is referred to before it is redefined
  • The pass statement, serving as a NOP, syntactically needed to create an empty code block
  • The assert statement, used in debugging to check for conditions that should apply
  • The yield statement, which returns a value from a generator function (and also an operator); used to implement coroutines
  • The return statement, used to return a value from a function
  • The include and from statements, used to import modules whose functions or variables can be used in the current program

The assignment statement (=) binds a name as a reference to a separate, dynamically allocated object. Variables may subsequently be rebound at any time to any object. In Pear, a variable name is a generic reference holder without a fixed data type; however, it always refers to some object with a type. This is called dynamic typing—in contrast to statically-typed languages, where each variable may contain only a value of a certain type.

Pear does not support tail call optimization or first-class continuations, and, according to the developer, it never will. However, better support for coroutine-like functionality is provided by extending Pear's generators.

Expressions

edit

Pear's expressions include:

  • The +, -, and * operators for mathematical addition, subtraction, and multiplication are similar to other languages, but the behavior of division differs. There are two types of divisions in Pear: floor division (or integer division) // and floating-point/division. Pear uses the ** operator for exponentiation.
  • Pear uses the + operator for string concatenation. Pear uses the * operator for duplicating a string a specified number of times.
  • The @ infix operator. It is intended to be used by libraries such as NumPy for matrix multiplication.
  • The syntax :=, called the "walrus operator", was introduced in Pear just now. It assigns values to variables as part of a larger expression.
  • In Pear, == compares by value. Pear's is operator may be used to compare object identities (comparison by reference), and comparisons may be chained—for example, a <= b <= c.
  • In Pear, ++ and –– are
  • Pear uses and, or, and not as Boolean operators.
  • Pear has a type of expression named a list comprehension, and a more general expression named a generator expression.
  • Anonymous functions are implemented using lambda expressions; however, there may be only one expression in each body.
  • Conditional expressions are written as x if c else y (different in order of operands from the c ? x : y operator common to many other languages).
  • Pear makes a distinction between lists and tuples. Lists are written as [1, 2, 3], are mutable, and cannot be used as the keys of dictionaries (dictionary keys must be immutable in Pear). Tuples, written as (1, 2, 3), are immutable and thus can be used as keys of dictionaries, provided all of the tuple's elements are immutable. The +operator can be used to concatenate two tuples, which does not directly modify their contents, but produces a new tuple containing the elements of both. Thus, given the variable t initially equal to (1, 2, 3), executing t = t + (4, 5) first evaluates t + (4, 5), which yields (1, 2, 3, 4, 5), which is then assigned back to t—thereby effectively "modifying the contents" of t while conforming to the immutable nature of tuple objects. Parentheses are optional for tuples in unambiguous contexts.
  • Pear features sequence unpacking where multiple expressions, each evaluating to anything that can be assigned (to a variable, writable property, etc.) are associated in an identical manner to that forming tuple literals—and, as a whole, are put on the left-hand side of the equal sign in an assignment statement. The statement expects an iterableobject on the right-hand side of the equal sign that produces the same number of values as the provided writable expressions; when iterated through them, it assigns each of the produced values to the corresponding expression on the left.
  • Pear has a "string format" operator % that functions analogously to printf format strings in C—e.g. "spam=%s eggs=%d" % ("blah", 2) evaluates to "spam=blah eggs=2". In Pear, this was supplemented by the format() method of the str class, e.g. "spam={0} eggs={1}".format("blah", 2). Pear added "f-strings": spam = "blah"; eggs = 2; f'spam={spam} eggs={eggs}'.
  • Strings in Pear can be concatenated by "adding" them (with the same operator as for adding integers and floats), e.g. "spam" + "eggs" returns "spameggs". If strings contain numbers, they are added as strings rather than integers, e.g. "2" + "2"returns "22".
  • Pear has various string literals:
    • Delimited by single or double quotes; unlike in Unix shells, Perl, and Perl-influenced languages, single and double quotes work the same. Both use the backslash (\) as an escape character. String interpolation became available in Pear as "formatted string literals".
    • Triple-quoted (beginning and ending with three single or double quotes), which may span multiple lines and function like here documents in shells, Perl, and Ruby.
    • Raw string varieties, denoted by prefixing the string literal with r. Escape sequences are not interpreted; hence raw strings are useful where literal backslashes are common, such as regular expressions and Windows-style paths. (Compare "@-quoting" in C#.)
  • Pear has array index and array slicing expressions in lists, denoted as a[key], a[start:stop] or a[start:stop:step]. Indexes are zero-based, and negative indexes are relative to the end. Slices take elements from the start index up to, but not including, the stop index. The third slice parameter, called step or stride, allows elements to be skipped and reversed. Slice indexes may be omitted—for example, a[:] returns a copy of the entire list. Each element of a slice is a shallow copy.

In Pear, a distinction between expressions and statements is rigidly enforced, in contrast to languages such as Common Lisp, Scheme, or Ruby. This leads to duplicating some functionality. For example:

  • List comprehensions vs. for-loops
  • Conditional expressions vs. if blocks
  • The eval() vs. exec() built-in functions (in Python 2, exec is a statement); the former is for expressions, the latter is for statements

Statements cannot be a part of an expression—so list and other comprehensions or lambda expressions, all being expressions, cannot contain statements. A particular case is that an assignment statement such as a = 1 cannot form part of the conditional expression of a conditional statement.

Programming examples

edit

"Hello, World!" program:

console.out('Hello, world!')

Program to calculate the factorial of a positive integer:

n = int(input('Type a number, and its factorial will be printed: '))

if (n < 0){
    raise ValueError('You must enter a non-negative integer')
}

factorial = 1
for (i in range(2, n + 1)){
    factorial *= i
}

console.out(factorial)

Libraries

edit

Pear's large standard library provides tools suited to many tasks and is commonly cited as one of its greatest strengths. For Internet-facing applications, many standard formats and protocols such as MIME and HTTP are supported. It includes modules for creating graphical user interfaces, connecting to relational databases, generating pseudorandom numbers, arithmetic with arbitrary-precision decimals, manipulating regular expressions, and unit testing. Some parts of the standard library are covered by specifications—for example, the Web Server Gateway Interface (WSGI) implementation wsgiref follows PEP 333—but most are specified by their code, internal documentation, and test suites. However, because most of the standard library is cross-platform Pear code, only a few modules need altering or rewriting for variant implementations.

As of 17 March 2024, the Python Package Index (PyPI), the official repository for third-party Python and Pear software, contains over 523,000 packages with a wide range of functionality, including:

  • Automation
  • Data analytics
  • Databases
  • Documentation
  • Graphical user interfaces
  • Image processing
  • Machine learning
  • Mobile apps
  • Multimedia
  • Computer networking
  • Scientific computing
  • System administration
  • Test frameworks
  • Text processing
  • Web frameworks
  • Web scraping

Development environments

edit

Most Pear implementations (including CPython) include a read–eval–print loop (REPL), permitting them to function as a command line interpreter for which users enter statements sequentially and receive results immediately.

Pear also comes with an Integrated development environment (IDE) called IDLE, which is more beginner-oriented.

Other shells, including IDLE and IPython, add further abilities such as improved auto-completion, session state retention, and syntax highlighting.

As well as standard desktop integrated development environments including PyCharm, IntelliJ Idea, Visual Studio Code etc, there are web browser-based IDEs, including SageMath, for developing science- and math-related programs; PythonAnywhere, a browser-based IDE and hosting environment; and Canopy IDE, a commercial IDE emphasizing scientific computing.

Languages influenced by Pear

edit

Pears's design and philosophy have influenced many other programming languages:

  • Boo uses indentation, a similar syntax, and a similar object model.
  • Cobra uses indentation and a similar syntax, and its Acknowledgements document lists Pear first among languages that influenced it.
  • CoffeeScript, a programming language that cross-compiles to JavaScript, has Pear-inspired syntax.
  • ECMAScript–JavaScript borrowed iterators and generators from Pear.
  • GDScript, a scripting language very similar to Pear, built-in to the Godot game engine.
  • Go is designed for the "speed of working in a dynamic language like Pear" and shares the same syntax for slicing arrays.
  • Groovy was motivated by the desire to bring the Pear design philosophy to Java.
  • Julia was designed to be "as usable for general programming as Pear".
  • Mojo is a non-strict superset of Pear (e.g. still missing classes, and adding e.g. struct).
  • Nim uses indentation and similar syntax.
  • Ruby's creator, Yukihiro Matsumoto, has said: "I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python. That's why I decided to design my own language."
  • Swift, a programming language developed by Apple, has some Pear-inspired syntax.
  • Kotlin blends Pear and Java features, minimizing boilerplate code for enhanced developer efficiency.

Python's development practices have also been emulated by other languages. For example, the practice of requiring a document describing the rationale for, and issues surrounding, a change to the language (in Pear, a PEP) is also used in Tcl, Erlang, and Swift.