zionlang / zion Goto Github PK
View Code? Open in Web Editor NEWA statically-typed strictly-evaluated garbage-collected readable programming language.
Home Page: https://zionlang.org/
License: Other
A statically-typed strictly-evaluated garbage-collected readable programming language.
Home Page: https://zionlang.org/
License: Other
This should be trivial but will probably looking at typeclasses. Think about whether % belongs in class Num
or not. Probably not.
tests/test_string_contains.zion:2:17: error: unbound variable in
tests/test_string_contains.zion:1:4: error: duplicate symbol test_string_contains.main (TODO: make this error better)
This area requires more experimentation.
Think about named struct initialization or named parameters.
fn main() {
# NB: this needs support for Char in pattern matching
match ('a', 1, 'c') {
(a, b, c) {
assert(a == 'a')
assert(b == 1)
assert(c == 'c')
}
}
__builtin_pass_test
}
This causes fallthrough to https://github.com/zionlang/zion/blob/master/src/match.cpp#L365
allow fallback to default implementations when a specialized implementation cannot be found
see example in lib/std.zion
:
class Eq a {
fn ==(a, a) Bool
fn !=(a, a) Bool
/*default {
fn ==(a, b) {
return not (a != b)
}
fn !=(a, b) {
return not (a == b)
}
}*/
}
class F x {
fn f(x) Int
}
class G x {
has F
fn g(x) Int
}
fn h(y) => g(y)
Should result in scheme (โ a . a -> Int) | [G a]
not (โ a . a -> Int) | [F a, G a]
because G a
implies F a
.
fn main() {
var sum := 0
static_print(sum)
}
Upon compilation this shows that the sum in the static_print (the Var ref) is being converted to std.sum. This is easier to see in the parsed output.
The problem is that the parser has no context on which variables are in scope, so it doesn't know to avoid ps.id_mapped behavior for those symbols. If possible, it would be nice to be able to collect exemptions from id mapping behavior in the parser id rewriting logic. I don't love that idea because it definitely exemplifies the complexity of the syntax. Other possibilities may exist...
The basic idea here is that currently the language allows partial implicitly.
This passes:
# test: pass
# expect: 6
# expect: 13
fn add(x, y) {
return x + y
}
fn main() {
g := add(3)
print(g(3))
print(g(10))
}
And, while that is cool and clever, it is not necessary to use that odd syntax. Further compounding the oddness of mixing C-style syntax for function calls with a functional lambda-calculus gooey inside, this passes:
# test: pass
# expect: 14
# expect: 17
fn partial_add(x) {
return fn (y) {
return x + y
}
}
fn main() {
print(partial_add(10, 4))
print(partial_add(9)(8))
}
The reason of course being that applying 4 to the application of 10 to partial_add
works perfectly well in the type system, and by the time the type system cares about it, it doesn't know the syntactic structure of the callsite.
The upside of this approach is that the compilation model is simpler when you throw away the C-style syntax. It might allow for more powerful code constructs, although I haven't figured out if that's actually true yet.
The thought I had was that in order to make this smell more like a standard function signature, arguments to functions would be implicitly wrapped in a pretend tuple during compilation, but that pretent tuple or group would be elided prior to code generation. This would have the effect of forcing the type-system to require the whole group at callsites, and would demand that the parser not automatically nest lambdas with single parameters for each parameter declaration at fn
sites.
The downside of this approach (apart from cost of implementation) is that language users now need to write out their own partials if they want them, and when they want to call a function returned by another function, they must "apply" two parameter groups. f(x)(y)
This is similar to Scala's partial application system.
We will use the split-and-join method.
a := 4
assert("hey {a}{f(x)}" == join("", ["hey" ", str(a), str(f(x))]))
The sigil ($, %, # or nothing at all) will require some thought.
fn g() {
return h(1)
}
fn h(x) Int {
return 3
}
fn main() {
x := g()
static_print(x)
}
The above fails to compile, however, when h
is declared first, it all resolves and compiles fine.
global initialization
Implicitly constructed tuples (type erasure) should be nice syntactically.
String((sz, length)) := "Hey"
could be
String(sz, length) := "Hey"
This should largely come down to needing to modify the reader macro in the parser, as well as the pattern matching code to just omit the ctor_id matching.. maybe checking for the arity of the pattern... etc...
Currently the FFI is all bespoke through the _builtin* functions. A better approach will be to create a small DSL for specifying extern types and signatures. First pass could be only function signatures.
One large component of this is handling system-specific int
sizes. Most libc functions, for example.
Could be something ugly at first like:
# int open(const char *pathname, int flags, mode_t mode);
extern fn open(pathname *Char, flags `int`, mode `int`)
So, lot's of things come up.
int
because its size is subject to .flags
is a grf and as such has declared (again target-specific) values that need to be available to the caller. Some process of (post-install) configuration or templatizing of the system zion files would be helpful.O_RDONLY
will need to be generated and injected into the program.All this syntax will need to result in the generation of either simple wrapper functions that then call through to a __builtin_ffi that knows how to propagate these params.
with x as y {
z(y)
} else error {
print(error)
}
becomes
match x {
ResourceAcquired(y, cleanup) {
defer cleanup
z(y)
}
Failure(error) {
print(error)
}
}
This means there needs to be a defer mechanism...
defer f
assumes f :: () -> ()
and calls it prior to leaving the enclosing block
this is needed for #15
Can you add printf
, sprintf
, fprintf
and more features from libc?
Goal: Implement escape analysis in order to avoid unnecessary heap allocations.
After translation, before gen phase, add a phase to annotate heap-exprs.
During gen phase, pay attention to heap-marks on tuples.
Something like {a: b, c: d}
, or [a: b, c: d]
.
Also should consider a Set
syntax, so that leans towards the {}
squiggly braces. Although, squiggly braces are used for block begin and block end, so that introduces some complexity...
Needed in order to have overloads for containers, streams, etc...
I have a few questions:
Is there any command line arguments parser (argc
, argv
)?
How to read user input?
Where I can find some docs?
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.