Coder Social home page Coder Social logo

zionlang / zion Goto Github PK

View Code? Open in Web Editor NEW
46.0 3.0 2.0 26.31 MB

A statically-typed strictly-evaluated garbage-collected readable programming language.

Home Page: https://zionlang.org/

License: Other

CMake 0.36% Dockerfile 0.05% Makefile 0.41% Shell 1.03% C 2.11% C++ 95.31% Roff 0.59% Vim Script 0.15%
zion programming-language compiler hindley-milner system-f typeclass static-typing garbage-collect lambda-calculus llvm

zion's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

yetamrra rgeez

zion's Issues

Implement % arithmetic

This should be trivial but will probably looking at typeclasses. Think about whether % belongs in class Num or not. Probably not.

fix duplicate symbol warning

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)

implement type class function default implementations

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)
        }
    }*/
}

Implement context simplification for subclasses

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.

imported symbols cannot be shadowed

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...

Grouped parameters

Grouped parameters

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.

Feature: string interpolation

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.

newtype constructor syntax could be better

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...

Need a generic FFI

FFI

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.

  1. Certain existing types can be mapped 1-1 over to C, like *Char.
  2. There needs to be a type declaration for referring to target-specific int because its size is subject to .
  3. 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.
  4. There should probably be something specifying the calling convention. fastcall, cdecl, etc... this might not be necessary if we assume for now that target machine calling conventions will be the same across APIs, and that LLVM will just take care of that for us.
  5. Values like O_RDONLY will need to be generated and injected into the program.

Code Generation

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.

implement with blocks

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...

Escape analysis

Escape analysis

Goal: Implement escape analysis in order to avoid unnecessary heap allocations.

After translation, before gen phase, add a phase to annotate heap-exprs.

Escape phase

  1. Build a usage graph of exprs.
  2. Find all exprs that have usage links to return statements or towards heap-marked exprs.
  3. For any tuples that link to return statements, mark them as heap.
  4. Goto 2 until no more exprs are marked.

During gen phase, pay attention to heap-marks on tuples.

Feature: associative array literal and set literal syntax

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...

Few questions.

@wbbradley

I have a few questions:

  1. Is there any command line arguments parser (argc, argv)?

  2. How to read user input?

  3. Where I can find some docs?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.