This repository was archived by the owner on Dec 8, 2022. It is now read-only.
Releases: seq-lang/seq
Releases · seq-lang/seq
v0.11.0
v0.10.3
- Fix illegal instruction error on Linux.
v0.10.2
- Improved Python standard module compatibility
- htslib is now statically linked with runtime library, so an external htslib is no longer needed
v0.10.1
seqcnow correctly reads from stdin by default or when passed-as input file- Other minor fixes
v0.10.0
Overview
Version 0.10 brings a slew of improvements to the language and compiler, including:
- Nearly all of Python’s syntax is now supported, including empty collections (
[],{}), lambda functions (lambda),*args/**kwargs,Noneand much more - Compiler error messages now pinpoint exactly where an error occured with compile-time backtraces
- Runtime exceptions now include backtraces with file names and line numbers in debug mode
- GDB and LLDB support
- Various syntax updates to further close the gap with Python
- Numerous standard library improvements
Detailed changes
seqc
The seqc command’s syntax and default behavior has changed in v0.10:
- Default is now “debug” mode, which disables most compiler optimizations but now shows full backtraces with file and line information, and allows for debugging with GDB/LLDB.
- Optimizations can be enable with “release” mode via the
-releaseflag. seqchas three modes to choose from (use-helpon any of these for more info):- Run: Runs the program directly with the JIT (
seqc run) - Build: Compile the program to an executable, object file or LLVM IR (
seqc build) - Doc: Generate documentation for a program based on docstrings (
seqc doc)
- Run: Runs the program directly with the JIT (
- If you just want to run a program:
seqc run program.seq
Type system
Seq 0.10 ships with the completely revamped bi-directional type system. Here is a short gist of the new type system in action:
a = []
for i in range(3):
a.append(i)
print a # it is a List[int] with [1, 2, 3]
b = None if len(a) else [1, 3] # b is Optional[List[int]]
b.append(3) # either appends 3 or raises an error if b is None
def foo[T: int, TA = int](a, b: Optional[Function[TA, TA]] = None):
if isinstance(TA, int):
if T < 4:
return a
else:
return 1.1
else:
return f'modified {b(a)+T}'
def adder(a, b):
return a + b ** 2
print foo[1](1) # 1 of type int
print foo[5](1) # 1.1 of type float
print foo[1](2, adder(3, ...)) # 'modified 8' of type stringMajor highlights:
- Automatic type deduction
a = [] a.append(1) print a
- Improved
Optional[T]handling (assignments,if-elseexpressions, calls and dot-expressions automatically wrap or unwrapOptional[T])a = None a = 5 # a is now Optional[int] a + 1 # 6 as a gets unwrapped b = 1 if foo() else None # b is Optional[int]
- Compile-time static integer types and expressions:
def foo[N: int](): print N foo[4]() # 4 # static integers can be passed from the command line: # seqc -DK=5 foo.seq k = Kmer[K] # becomes Kmer[5] k = Kmer[1 if K > 2 else 4] # also works as this is a static expression if K > 3: # <something>; compiled only if K > 3 at the compiile-time else: # <something else>
- Compile-time type checks
- new compile-time
isinstance,hasattrandstaticlen, as well as compile-time static expressions
- new compile-time
- Improved support for partial functions
Improved Python support
All Python objects are not first-class Seq objects:
from python import numpy as np
a = np.array(2, 2)
print a[0,1].pow()Syntax changes
Tuple classes:
@tuple
class Foo: # instead of type Foo(x: T)
x: TType extension:
@extend
class Foo: # instead of extend FooAuto-deduction of self type:
class Foo[T]:
def bar(self, x): # instead of bar(self: Foo[T], x)Support for lambdas:
print list(map(range(5), lambda x: x + 1)) # [1, 2, 3, 4, 5]Python 3 print function:
print(a, b, sep='~', end='!', file=fo)
print a # this is still supportedMypy-style naming:
List[int] # not list[int]
Dict[int, Tuple[int]] # not dict[int,tuple[int]]
Callable[[int, int], void] # not function[void,int,int]Relative and recursive import support:
from .. import fooC, Python and LLVM imports:
from C import pow(float, float) -> float # instead of cimport pow
from C import library.foo(int)
from python import numpy
from python import os.system(str) -> str # instead of pyimport
@python
def foo(): # instead of pydef foo()
print sys.path
@llvm
def bar(x: T) -> Ptr[byte]:
%0 = {=T}* nullptr
ret i8* %0Walrus (assign) expression:
if (x := foo()):
print xloop-else support
for i in bar(): pass
else: print 'no break'
while foo(): pass
else: print 'no break'Other changes
- Improved Ints:
- Unsigned integers:
123u - Fixed-width integers:
12i14or234u615- Uses
Int[N].__new__(str)to parse such numbers
- Uses
- Binary representation:
010101b - Digit separator:
123_456or0001_0101b - Custom suffixes:
123sfx→int.__suffix_sfx__("123")
- Unsigned integers:
- Improved Float lexing:
- Custom suffixes:
123.sfx→float.__suffix_sfx__("123.") 1e2is parsed as a float, not as an integer with suffixe2
- Custom suffixes:
- Improved String handling:
- Custom prefixes:
pfx"hi"→str.__prefix_pfx__[2]("hi")(length si passed as a static integer)
- Custom prefixes:
- Better unpacking support:
- List unpacking:
[1, *args, 2]ifargssupports__iter__ - Set unpacking:
{1, *args, 2}ifargssupports__iter__ - Dictionary unpacking:
{a: b, **args}ifargssupports__iter__that returnsTuple[K, V] - Call unpacking:
foo(a, *args, **kwargs)argsmust be a tuple (lists and named t won’t work). Named tuples are OK.kwargsmust be a named tuple (@tuple class)
- Support variable unpacking in
forloops and comprehensions:for i, *_, (k, l) in fooor[a(b) for _, b in c.items()]
- List unpacking:
- Static evaluation
- integers, Booleans, ternary operator
a if b else c, unary operators[not,-], binary operators[+,-,*,//,%], conditional operators[==,!=,<,<=,>,>=,and,or]and the following static calls:staticlen(tuple)isinstance(var, type)hasattr(type, "attr")compile_error("str")
- integers, Booleans, ternary operator
- Named and default argument support for partial functions:
def foo(a, b, c=1): … ; p = foo(1, …, …); p(b=2) - All partial functions must be explicitly annotated with
…(no more auto-partialization except in pipe expression) - Unified slice type
Slice[Optional[int],Optional[int,Optional[int]]forstart:stop:step - Assign (walrus) expression:
if a := foo(): …- Valid only in its own block
- Not allowed in a short-circuiting expressions:
if a or (b := foo())won’t compile
__ptr__is a proper expression now- Assign statements support type annotations:
a: List[int] = [] - Proper
printfunctionprintfollowed by a whitespace is a statement;printthat is not is a identifier
- Improved
assertstatement:assert foo(), f"Failed! {bar}" - Heterogeneous tuple iteration in
forloop:a = (1, 's', 5.5); for i in a: print(i)- Each iteration is a separate block
- User needs to ensure that enclosing types are not incorrectly used
- Cannot be composed with other iterators (e.g.
for i, a in enumerate((1, 's')): …)
- Improved
matchstatement:- Each
casechecks for correct type; if a expression type is incorrect, the corresponding case is ignored - Support custom matching via
__match__magic case x or yis nowcase x | y
- Each
- Better import support
- Support for recursive importing
- Support for Python-style import execution (order of import execution is decided at runtime)
- New tuple magic:
__dict__(self) -> List[str]that returns list of class member names __contains__works on heterogeneous tuples- Each module exposes
__name__ - Improved
a is bcheck - Better slices (via
Slice()) Optional[T]andpyobjforward their method calls- Support for custom atomic updates (
__atomic_op__and__atomic_xchg__)
v0.9.11
- Inter-sequence alignment kernel now portable by choosing SIMD instruction set at runtime
- SAM/BAM error handling improvements and API additions
- Bug fixes:
- Fixed an issue caused by raising exceptions from properties
- Fixed an inter-sequence alignment flush issue