Pythonect 0.1.0 Release

Hi All,

I'm pleased to announce the first beta release of Pythonect interpreter.

Pythonect is a new, experimental, general-purpose dataflow programming language based on Python.

It aims to combine the intuitive feel of shell scripting (and all of its perks like implicit parallelism) with the flexibility and agility of Python.

Pythonect interpreter (and reference implementation) is written in Python, and is available under the BSD license.

Here's a quick tour of Pythonect:

The canonical "Hello, world" example program in Pythonect:

>>> "Hello World" -> print
<MainProcess:Thread-1> : Hello World
Hello World
>>>

'->' and '|' are both Pythonect operators.

The pipe operator (i.e. '|') passes one item at a item, while the other operator passes all items at once.

Python statements and other None-returning function are acting as a pass-through:

>>> "Hello World" -> print -> print
<MainProcess:Thread-2> : Hello World
<MainProcess:Thread-2> : Hello World
Hello World
>>>

>>> 1 -> import math -> math.log
0.0
>>>

Parallelization in Pythonect:

>>> "Hello World" -> [ print , print ]
<MainProcess:Thread-4> : Hello World
<MainProcess:Thread-5> : Hello World
['Hello World', 'Hello World']

>>> range(0,3) -> import math -> math.sqrt
[0.0, 1.0, 1.4142135623730951]
>>>

In the future, I am planning on adding support for multi-processing, and even distributed computing.

The '_' identifier allow access to current item:

>>> "Hello World" -> [ print , print ] -> _ + " and Python"
<MainProcess:Thread-7> : Hello World
<MainProcess:Thread-8> : Hello World
['Hello World and Python', 'Hello World and Python']
>>>

>>> [ 1 , 2 ] -> _**_
[1, 4]
>>>

True/False return values as filters:

>>> "Hello World" -> _ == "Hello World" -> print
<MainProcess:Thread-9> : Hello World
>>>

>>> "Hello World" -> _ == "Hello World1" -> print
False
>>>

>>> range(1,10) -> _ % 2 == 0
[2, 4, 6, 8]
>>>

Last but not least, I have also added extra syntax for making remote procedure call easy:

>>> 1 -> inc@xmlrpc://localhost:8000 -> print
<MainProcess:Thread-2> : 2
2
>>>

Download Pythonect v0.1.0 from: http://github.com/downloads/ikotler/pythonect/Pythonect-0.1.0.tar.gz

More information can be found at: http://www.pythonect.org

I will appreciate any input / feedback that you can give me.

Thanks,

Itzik Kotler

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Chaining import

Interesting. But why doesn't this work?

>>> import math
>>> 1 -> math.log
math.log

Re: Chaining import

Hi,

Good question.

`import math` can be connected to `1` in two ways: async or sync.

Currently (v0.1.0), I make no assumption toward the connection type between two components and required it to be explicity specified. Similar to `1 -> math.log`.

In your case, `import math` was treated as a program (executed, returned None, did not print the return value to the screen). And, `1 -> math.log` was treated as a program (executed, and an Exception raised, resulted in priting the component which caused the Exception). Each with it's own scope, and context.

Perhaps, there's a place to exclude pure Python statements such as `import` and `variable assignments` from the need to be explicity connected to another component. So:

import math
1 -> math.log

Will be equal to

import math -> 1 -> math.log

Data flow and definition flow

Your system is conflating data flow with lexical environment scope. Kartik expected them to be separate entities. I suppose he could also have expected the following to work (does it)?


>> hello = "Hello World"
>> hello -> print

I don't think it would make sense to make special-case for some environment-changing construct (import) but not others. You should rather make a design choice about whether data flow and lexical environment flow are unified or not. I have little experience with dataflow-programming, maybe it doesn't make sense or is really inconvenient to separate environment flow.

Another way to solve the problem would be to rethink the meaning of the toplevel in term of dataflow (instead of simply having separate executions). In non-imperative languages, the meaning of a toplevel program is often explained by a translation to a single expression. For example in OCaml, the following code, when evaluated to the toplevel

let x = foo;;
bar;;
let y = baz;;

could be explained as the following expression using local binding only:

let x = foo in
  bar;
    let y = baz in
       ()

(Remark: this is not a precise translation as long as compilation unit and separate compilation are considered.)

Similarly, you could define the meaning of toplevel programs by using data flow constructs.


>>import foo
>>bar
>> baz

could be said to be equivalent to

import foo -> bar -> baz

except with interactive result printing.

This would make the above program work (while preserving unification of the global toplevel environment scope and the data flow), and would justify the feature (that you may already have) that '_' in the first expression of a toplevel item refers to the result of the previous computation.

Re: Data flow and definition flow

You are right. My system is conflating data flow with lexical environment scope.

I will think more about it.

Thank you for your feedback.