Rem language is currently implemented by CPython, and it's for people who're working on the fields of Python, Julia, R or MATLAB .etc...
Rem looks like Python, Ruby and many other dynamic languages, and it adopts some convenient features from many functional programming languages.
The inverted syntax in Rem is the core in some degree. As the result of unifying the manipulations on first-class functions, you can write these object-oriented-like codes in the following way:
>> ["foo", "bar"] . map {|x| x + "tail"}
However it's not really object-oriented, it's functional!
To explain, the codes above could be represented in Python codes:
map (lambda x: x + "tail", ["foo", "bar"])
(Just take care that not all the codes in Rem can be directly translated to Python.
Also, we can try to imitate keyword
with functions in Rem:
let x = 0
while { x < 10} {
x = x + 1
}
And while
here is just a function!
Pattern Matching and Where Syntax are both tasty, too. You can learn how to use them in the following manual.
All in all, Rem has a lot of features to support comfortable programming with modern paradigms.
I'm planning to write a C# backend for Rem sooner in order to get rid of too much Python(however we shouldn't ignore the requirements of works in real world), and efficient compilers will come up, too.
Install remlang
easily by using PyPI with Python 3.6+.
pip install remlang
If you want to use the repl
, just type irem
:
irem
Rem Language alpha, March 15 2018 02:14.
Backend CPython, Author thautwarm, MIT License.
Report at https://github.com/thautwarm/Rem/issues.
>> "Hello World"
'Hello World'
>> "Hello World" . print
Hello World
Something you need to take care is that Functions are curried in Rem.
>> let fn = {|x| x + 1}
>> fn 1
=> 2
>> let fn = {|x, y, z|
y = y + z + x
y
}
>> f1 = fn 5
>> f2 = fn 10
>> fn 20
=> 35
=> from x, y, z let x + y + z end # another way to define a lambda
=> {x, y, z => x + y + z} # another way to define a lambda
You can make a lambda
with the syntax you prefer:
-
JavaScript like:
{x, y => x + y}; {{"a": a}, (b, c) => a + b + c}
-
Ruby like:
{|x, y| x + y}, {|{"a": a}; (b, c)| a + b + c }
-
Natural language like
from x, y let x + y end from {"a": a}, (b, c) let a + b + c end
A very sweet syntax sugar from Scala
is now supported.
>> 1 . {_ + 1}
=> 2
>> [1, 2, 3] . map {_ + 1} . list
=> [2, 3, 4]
>> {_1 + _2} 1 2
=> 3
Take care that when you're using multiple implicit parameters, you cannot curry it.
So the following codes would cause runtime error.
>> let f = {_1 + _2} 1
>> let fn = {|x| x**2}
>> fn 2 + 3
=> 7 # 2**2 + 3
>> fn $ 2 + 3
=> 25 # (2+3) ** 2
>> let fn = {|x, y| x*y}
>> fn $ 1+2 $ 3+4
=> 21 # 3*7
Partly Dynamic Scoping
>> let x = 0
>> call { x }
=> 0
>> call { x = 1; x}
=> 1
>> x
=> 1
>> call {let x = x; x = 10; x}
=> 10
>> x
=> 1
>> dictionary = %{
c where
c = 1
end : 2
}
>> dictionary
=> {1: 2}
>> from math import pi
>> S = S1 + 2*S2 where
let S1 = pi*r**2
let S2 = 2*pi*r
end
>> let add = {|x, y| x + y}
>> 1 . add 2
=> 3
>> 1 then add 2
=> 3
However, the priority of .
is different from then
.
Here is the table of priorities in Rem:
syntax | priority | sample |
---|---|---|
then | 1 | a then func |
$ |
1 | f $ 1 2 |
case | 2 | case ... end |
binary expr | 2 | 1 * 2 |
unary expr | 3 | a? , a?? , not a |
. (inverted) |
4 | a . add |
function call | 4 | f 1 2 , call f |
expr with trailers | 5 | a'name , a![0] |
atom | 6 | lambda and so on |
>> let concat = {|x| print x ; {|y| print y ;x ++ y}}
>> "left" . concat "right"
left
=> "leftright"
>> "right" then concat "left"
right
=> "rightleft"
Both of them are left associative.
Make a generator
>> from [1, 2, 3] yield {|x| x+1} . list
=> [2, 3, 4]
>> from [1, 2, 3], ["a", "b", "c"] yield {|a, b| (a, b)} . list
=> [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]
- for-loop:
not yield
>>> from [1, 2, 3] not yield {|x|
print x
x
}
1
2
3
=> 3
Very powerfull and can even be the alternative of if-else
.
case (1, 2, 3)
as 1, ...a when
a![0] == 2
=> a
as _ => raise
end
You can use it for only destruction:
>> case (1, 2, 3) as (a, b, c) end
>> print a*b*c
=> 6
>> let t = case (1, 2, (3, 5, (6, 5))) as [1, 2, [3, 5, [6,...a]]] => a end
>> t
=> <tuple_iterator object at 0x0000017689F95FD0>
>> t. tuple
=> (5, )
>> case
%{1: [1, 2, 3], 2: [2, 3, 4]}
as
{1: a, 2: b}
end
>> (a, b)
=> ([1, 2, 3], [2, 3, 4])
The return of pack
destruction(...a
) is of type tuple when length is 1, or it's of type
tuple_iterator.
It is similar to goto
, but I add some constraints on it: you cannot go to the previous steps,
but you can jump out of current closure until you're in specific closure.
If you want to use into
in for comprehension
>> @here
>> from [1, 2, 3] not yield {|x|
into here
print x
}
>> from [1, 2, 3] not yield {|x|
print x
}
1
2
3
=> 3
Take care that the literal construction of list
, tuple
, set
and dict
will ignore the into
keyword, as well as from ... not yield ...
for-loop.
List: Just Python list
>> let l1 = [
1,
2,
c where
let c = 3
end,
4
]
>> l1 ++ [1, 2, 3] then list
=> [1, 2, 3, 4, 1, 2, 3]
>> l1 -- [1, 2, 3]
=> [4]
Dict: Just Python dict
>> let d1 = %{
1: 2,
expr where
let expr = 3
end : 4
}
Set is also Python set
as well as tuple
.
- Access Member and Index
# access member
>> import math
>> math 'pi
=> 3.141592653589793
>> math 'pi '__class__
=> <class 'float'>
# index
>> import numpy as np
>> let arr_cons = np 'ndarray
>> arr_cons [1, 2, 3]
=> array([[1, 2, 3]])
>> (arr_cons [[1, 2, 3]]) . slice [0, (1, 2)]
=> array([2])
>> (arr_cons [[1, 2, 3]]) ![indexer [0, (1, 2)]]
=> array([2])
>> (arr_cons [[1, 2, 3]]) ![0]
=> array([1, 2, 3])
/* define class here */
let class = {
|fn_dict|
# constructor
{
let self = call Object
from
fn_dict 'items then call
not yield {
|tp|
case tp as k, v
=>
self. set k (v self)
end
}
self
}
}
# spec
let cls1 = class %{
"go": {|x, y| y},
}
let inst = call cls1
inst'go 1
附: 中英文token对照
English | 中文 |
---|---|
then | 然后 |
when | 当 |
and | 并且 |
or | 或者 |
in | 含于 |
not | 非 |
case | 对于 |
as | 作为 |
end | 结束 |
where | 其中 |
from | 从 |
import | 导入 |
yield | 生成 |
into | 跳跃到 |
let | 使/让 |
True | 真 |
False | 假 |
None | 空 |
is | 是 |
. |
之 |