Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save temoto/179736 to your computer and use it in GitHub Desktop.
Save temoto/179736 to your computer and use it in GitHub Desktop.
a better programming language features

Types

  • Atoms (Erlang, Ruby)
>>> ok
>>> :ok
  • Infinite size integers

    Fallback to 32/64 bit "system integers" is a good optimization.

>>> i = 19999999999999999999999999999999999999999
  • First-class functions (C, Erlang, Haskell, Python, Ruby, etc) as opposed to Java.
>>> def f g = g 10   # same as python   def f(g): return g(10)
  • Lists/Tuples

    List/tuple is an ordered sequence of any values.

>>> {:error, "description"}
  • Unicode strings (Python3, Ruby)
>>> "Hello, world! (and other Unicode chars here)"

Code organization

Most concepts apply to pretty much any language.

  • Namespace.

    Namespace is a named collection of types, functions, etc. program blocks.

    Namespaces may be nested.

    There is a special named namespace global which is accessible from any point in program.

  • Source code container. Most typically - file.

    Source code may be taken from user input (REPL interpreter), from network, database, etc.

  • Modules.

    Module is a namespace living in a separate source code container.

  • Package.

    Package is a named, authored, licensed collection of modules and interfaces.

  • Interfaces. Modules provide (implement) interfaces: set of functionality.

    Most close analogy is C header files (module interface) and compiled library (implementation). A better language must be able to provide late binding of implementation to interfaces (just like C linking).

    I.e., interface Map (associative array) may be implemented via hash-table, binary tree, trie, etc. Developer doesn't specify implementation in source, because it's irrelevant.

    All implementations have equal interface and interface is the only thing you can touch.

Execution

  • Tail call optimization (Erlang, Haskell, Lisp) and not restricted to same function Simply speaking, a language must avoid CALL/RET instructions at all costs.

  • Lazy evaluation (Erlang, Haskell, Lisp)

    But there must be some means to enforce evaluation right now. That said, sometimes programmer do needs to specify computation/IO order. Don't stand in his way to do that.

    TODO: expand

  • Light threads running in few OS threads to exploit SMP (Erlang, Haskell)

Features

  • Pattern matching (Erlang, Haskell)
>>> def fib 0 = 0
>>>   1 = 1
>>>   x = fib (x - 1) + fib (x - 2)
>>>   x | x < 0 = :error   #  returns :error if x < 0
  • Futures (Alice ML, E, Haskell, Io)

    Evaluation of expressions in background. Immediate result is assigned with a special value that will hold the actual result when evaluation completes.

>>> x = future func
>>> # some costly operation
>>> print x   # will block until func is evaluated *if it is not yet*
  • Design by Contract (C#, D, Eiffel, guard expressions in Erlang, Haskell)

    Formal rules of interfaces interaction.

    Interface may impose some obligations on user, such as malloc(size) requires size to be > 0.

    Interface may provide some guarantees, such as int + 0 never fails (no exceptions will be raised).

  • IO is a fundamental concept, not just another FFI library

    TODO: expand

  • Type inference (C#, C++0x, D, Haskell, Ocaml)

    Automatic type guessing.

>>> x = [3..8] # x is of type List

Syntax

Machine serves human, not vise-versa. If machine can guess it without ambiguity, you don't have to write it.

  • Clean, simple syntax (Haskell)
  • Indentation-guided blocks (Python, Ruby)
>>> if x
>>>   do_this
>>>   do_that
>>> if y: continue
  • First-class regular expressions (Javascript, Perl, Ruby)
>>> if x ~ /^(exit|quit)$/i : break
  • No excessive brackets function call (Haskell, Ruby)
>>> x = f arg1
  • Multiline strings (Python, Ruby)
>>> s = """foo
>>> bar"""
  • Named regions of bits (C, Erlang)

    Named regions of bit vectors.

>>> typedef UTF8_like = bits {1: is_last, 7: data}  # defines a type 8 bits long, first bit is accesible as `is_last` member, others as `data` member
  • List comprehensions (Erlang, Haskell, Python, Ruby, etc)
>>> [3..] # infinite list of 3,4,5,...
>>> [x * 2 for x in [1..5]] # 2,4,6,8,10
TODO: maybe LCs don't need surrounding []
  • Dict compehensions (Python3)
>>> names = ["foo", "bar", "zar"]
>>> {a: 0 for a in names} # results in {'foo': 0, 'bar': 0, 'zar': 0}
  • List item access by index
>>> list[5]
Negative indexes mean 'from end'
>>> list = [1..10]
>>> list[-1] # 10
  • Lambda

    Anonymous functions. Different languages provide different syntax.

>>> (\x -> x * x + x) 3 # 12
>>> (lambda x: x * x + x) 3
>>> (x => x * x + x) 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment