Skip to content

Alore python unification

JukkaL edited this page Nov 8, 2011 · 26 revisions

All of these just preliminary ideas at the moment. None of these might see the light of day.

Potential changes

It may make sense to make Alore syntax and libraries resemble Python more to make it easier to switch to/from Python. Here are some ideas:

  • Use # for comments
  • Use indentation-based syntax
    • Do not require colon to retain Alore trademark look & feel?
    • 4 spaces for indent
    • Also add pass for empty block
    • Remove repeat..until
    • Maybe allow optional end markers for HTML templates etc. or for programmers who fear that editor will eat their whitespace ;-)
  • One-liner statements and function definitions
    • if cond: stmt, while cond: stmt (also for)
    • def foo(...): expr
      • No return for short-hand functions? (or only for short-hand anonymous functions)
      • Also lambda-style def (...): expr
        • Or no parens for a clearner look: def arg, ...: expr (seems like a winner)
        • Infer the return type, so def x as int: x + 1 has int return type
      • Multiline anonymous functions possible
  • Use Python-like naming conventions (but maybe more consistent)
    • foo_bar for globals and methods, e.g. chr, has_key
    • foobar for common names, e.g. startswith
    • Built-in types int, str, bool, list, dict etc. instead of Int etc.
    • Or maybe it's better to only start global functions with a lowercase letter but use camelCase
  • Use // instead of div, % instead of mod
  • Use % instead of format for string formatting
    • Also use %s etc. instead of {}
    • Or make format more like Python
  • Escape sequences in string literals (\n etc.)
    • Also raw strings r'foo'
    • Make text streams convert \n to platform-specific line break
  • Triple-quoted strings
    • Can be used as comments
  • Python style importing
    • import foo => have to use foo.bar
    • from foo import * similar to traditional import foo
    • But still use compile-time scoping, so from foo import * is (mostly) safe to use
    • Or import foo as currently, but also support from foo import x, y, ...
  • Newline conversion in text streams
    • Automatically convert \n to platform newline sequence when reading/writing streams
  • file(foo, 'w') instead of file(foo, output) (etc.)
  • Make print(...) more like in python
    • Separate arguments by spaces
  • Dictionary expressions { key: item, ... }
  • Use range(n) instead of 0 to n
  • Use None instead of nil
  • Unify library naming and behavior for the most common features
    • Not important to get 100% matching, since optional typing and other differences work against it
    • Use len(x) instead of x.length()
  • Bitwise operators such as &, | etc.
  • Hex int literals like 0x12abc
  • Add continue statement
  • Rename Alore to something else
    • Even though most changes are syntactic, Alore will really be a new language after all these changes

Not sure about these:

  • No need to declare local and global variables
    • Must use self.x = y to assign to a member (otherwise define a local variable)
    • Must use ::x = y to assign to a global variable in current module
    • Maybe also use ::x to assign to a local defined in an outer scope
    • Declare variable using x as Foo or x = ... as Foo
      • Or just x Foo or x Foo = ...
    • Declare member variable by simply giving the name in class body (x) or by assigning (x = 1) or by giving the type (x as int or x int)
  • Make file available by default (no need to import io)
  • Store program path as sys.argv[0]
    • This does not feel very intuitive, but it affects many scripts
  • Allow using None, ints, strings, lists and re match results as booleans (e.g. '' acts like False)
    • Maybe by default any non-None object is True
  • Do not require subdirectories for modules
  • Do not require module header
  • Use dot for scope separator (os.join instead of os::join)
  • Boolean operators return one of the operands, e.g. foo() or 'default'
  • Make special method names more like Python (__add__ etc.)
    • But maybe init instead of __init__ as this is very common (similar to main function)

Rejected changes

These changes are unlikely:

  • Explicit self everywhere (rejected)
    • This would be just too painful
    • Since we have static scoping, this does not really make sense
    • Programmers can always insert extra self. prefixes if they want
  • Use underscore for private (rejected)
    • Don't see the appeal
    • Makes code look uglier when following good practices such as encapsulation (bad)
    • Makes it more difficult to make private members public & vice versa (requires renaming)
    • We have automatic getters/setters which reduce the need of having similar names for public&private members
    • Maybe allow putting private on the previous line for a cleaner look

Plan

General ideas:

  • Implement as many features as possible without breaking (too much) existing code
    • Keep two versions of features during transition
  • Implement tools for performing automatic conversion
    • The parser in Alore type checker can already output the parse tree using original formatting; use it as a basis
    • Translating code manually is too slow, boring and error-prone
  • Maybe scrap the C bytecode compiler, and switch to using only the Alore parser implementation
    • New language features can be implemented much more quickly
    • Much less code to maintain
    • Basically requires the Alore native code compiler, as otherwise the parser would probably be too slow as the only available implementation

Implementation order:

  • Add # comments (no breakage)
  • Add indentation-based syntax (limited breakage if end is optional)
  • More Python-like naming (limited breakage; keep two versions of changed names)
    • Make global definitions other than types and constants start with a lowercase letter
    • So Main => main, Ord => ord, IsFile => isFile but Int, File and Newline remain
    • Maybe int(x) is a function; use Int only for annotations, casts and runtime type checks
  • Single-liner statements (limited breakage: pair expressions)
  • Rename div => // (no breakage if div is supported during transition)
  • Rename mod => % (no breakage if mod is supported during transition)
  • len(x) instead of x.length()
    • len is one of the most frequently-used operations; it's idiomatic in python code
    • Or maybe a compromise: x.length (getter)
  • This should be enough; potentially add more stuff later

Implementing the above list should be enough to make Alore code about as concise as Python.

Although not directly related to Python, the above changes would make it more convenient syntactically to support map and filter, perhaps making list comprehensions non-essential, at least initially:

map(collection, def x: x + 1)
filter(collection, def x: x < 2)

Or:

collection.map(def x: x + 1)   # is this better?

Discussion

Implicit variable declarations have these potential issues:

  • Makes it quicker and more convenient to write code, especially scripts, and generally gives code a cleaner look
    • But could actually make maintainability worse and refactoring more error-prone
  • May not play perfectly with optional typing and type inference (but probably can be made to work quite nicely)
  • Member variables need to be declared anyway, so there is a slight inconsistency
  • Makes const declarations feel like extra work, which is slightly bad