Giter VIP home page Giter VIP logo

cicada-lang / cicada-plct Goto Github PK

View Code? Open in Web Editor NEW
91.0 3.0 6.0 2.56 MB

Cicada Language (PLCT little team)

Home Page: https://cicada-lang.org

License: GNU General Public License v3.0

TypeScript 99.92% JavaScript 0.08%
cicada dependent-record-types dependent-type-theory dependent-types interactive-theorem-proving language programming-language prover repl theorem-prover type-system type-theory

cicada-plct's Issues

[feature] module system

Problem:

We need a module system.

Solution 1:

Importing with full file name including extension.

Be able to import from relative path.

  • Relative to current URL or file system path.

Be able to importing from URL.

[feature] support recursion

Problem:

We need to support writing recursive function directly, beside using recursive combinators.

Solution 1:

Implement Coq like fixpoint, readback should handle fixpoint to avoid infinite loop.

[feature] unification between two `Sigma`s

Problem:

Suppose we have the following definition of my_car and my_cdr:

function my_car(
  implicit A: Type,
  implicit B: (x: A) -> Type,
  pair: exists (x: A) B(x)
): A {
  return car(pair)
}

function my_cdr(
  implicit A: Type,
  implicit B: (x: A) -> Type,
  pair: exists (x: A) B(x),
): B(car(pair)) {
  return cdr(pair)
}

Given my_car(cons("a", "b")),
we can infer cons("a", "b") to be exists (_: String) String.

Then we must be able to solve the following equation:

solve (A: Type, B: (x: A) -> Type) {
  unify exists (x: A) B(x) = exists (_: String) String
}

The same problem occurs for unification between two Pis.

[design] about sequence

  • We want to use { x, y, z } for object literal sugar for { x: x, y: y, z: z }

  • Thus { x } is an object literal

  • We also want to use { ... } for a sequence of code -- for example let

    {
      let x = ...
      f(x)
    }
    
  • If we do not use return statement in sequence,
    we can not distinguish { x } from { return x }.

  • If we use return in sequence, we can write something like:

    let y = { return x }
    

    which reads bad, because return sounds like an early return from function.

  • What should we do?

[bug] Scope problem of implicit argument and fulfilling class type

class Isomorphism {
  cat: Category
  dom: cat.Object
  cod: cat.Object
  morphism: cat.Morphism(dom, cod)
  inverse: cat.Morphism(cod, dom)

  inverse_left: Equal(
    cat.Morphism(dom, dom),
    cat.compose(morphism, inverse),
    cat.id(dom),
  )

  inverse_right: Equal(
    cat.Morphism(cod, cod),
    cat.compose(inverse, morphism),
    cat.id(cod),
  )
}

Problem:

  • cat.compose is a PiImplicit.
  • take the cat.compose(morphism, inverse) in inverse_left as example.
  • elaboration will insert ApImplicit based on the type of morphism,
    get cat.compose(implicit x1, implicit x2, morphism, implicit x3, inverse).
  • solve it, get cat.compose(implicit dom, implicit dom, morphism, implicit dom, inverse),
    we write it like this, but actually solved value will not be substituted in place,
    but be saved in the env of the closure as x1 => dom.
  • now dom is in scope, but only have type dom: cat.Object, no value, thus it is a neutral variable.
  • in the following code block, fulfilling class type Isomorphism(cat, x.object, y.object)
    will provide the value of dom -- x.object.
  • during fulfilling class type, when evaluating inverse_left's type,
    we have dom => x.object and x1 => dom in scope,
    evaluate variable x1 will only get the neutral variable dom,
    but not going further to get the value of dom -- x.object,
    this is the problem.
import { Isomorphism } from "../category/index.cic"
import { equal_swap, equal_compose } from "../equality/index.cic"

function terminal_object_isomorphism(
  cat: Category,
  x: Terminal(cat),
  y: Terminal(cat),
): Isomorphism(cat, x.object, y.object) {
  let f = x.morphism(y.object)
  let g = y.morphism(x.object)

  return {
    cat,
    dom: x.object,
    cod: y.object,
    morphism: y.morphism(x.object),
    inverse: x.morphism(y.object),

    inverse_left: equal_compose(
      x.morphism_unique(cat.compose(g, f)),
      equal_swap(x.morphism_unique(cat.id(x.object))),
    ),

    inverse_right: equal_compose(
      y.morphism_unique(cat.compose(f, g)),
      equal_swap(y.morphism_unique(cat.id(y.object))),
    ),
  }
}

Solution 1:

Use substInEnv.


It might be not enough for substInEnv to only handle variable,
maybe we also need to handle all Values
-- like deep walk
-- maybe called advanceByEnv (v.s. advanceBySolution).

[feature] equivalence

Problem:

We need a built-in type for equivalence.

Solution 1:

Implement "the little typer"-like Equal:

  • Equal
  • Replace
  • Refl
  • Same

[feature] implicit

Problem:

During check of an Exp of type ImplicitPi,
use the information from the given type
to solve (typed) pattern variables in the ImplicitPi,
and use the Solution to insert ImplicitAp to the original Exp.

During infer of an Ap expression,
if the target of the Ap is of ImplicitAp,
we might infer some of its arguments' type,
use the information from these argTypes
to solve (typed) pattern variables in the ImplicitPi,
and use the Solution to insert ImplicitAp to the original Ap.

Constraints:

We should first be clear about the constraints (maybe the following).

  • During infer, an application f(x, y, z) of an expression f
    of ImplicitPi type (implicit A: Type, x: String, y: Pair(A, A), z: String) -> A,
    must resolve all of its pattern variables in this infer.

    • Application can curry, as long as it resolve all pattern variables.

    • f(x, y) -- ok

    • f(x) -- not ok

  • During check, an application check f(x, y, z): String
    can use return type to resolve pattern variables.

  • During check, a variable expression check id: (String) -> String
    of ImplicitPi type id: (implicit A: Type) -> (A) -> A
    must resolve all of its pattern variables using the given type.

  • The above constraints require a new constraint:

    • All pattern variables must occur at the start of the FoldedPi.

    If we break this constraint, we may say
    "must resolve all of its pattern variables until next ImplicitPi"
    instead of "must resolve all of its pattern variables".

[DX] standard formatter

Problem:

We need a standard formatter.

To help users avoid arguing about code formating.

Solution 1:

Implement formatExp and formatStmt(s).

These functions should take formatting context as argument,
and recurse down the Exp and Stmt.

Solution 2:

Learn from prettier API, and write prettier plugin.

https://prettier.io/docs/en/plugins.html

[design] the syntax of function

After adding the return type support, the function experssion will be written like:

function(x: String): String x 

It's strange to put return type and the body of function on an equal footing.

As we have (x: String) => x for the simple function, we can use function-style only for the complex function with Sequence on the body:

function(x: String): String {
  return x
}

[design] consistency levels

Problem:

We need a way to distinguish consistency levels.

For examples:

  • side effect
  • type in type

Solution 1:

One module, one consistency level.

Use file extension to distinguish consistency levels.

  • .c0, .c1, .c2, ...

Higher level can not import lower level module.

[feature] inductive datatype

Problem:

We need to support inductive datatype to let user define new types.

Solution 1:

Maybe add the following new values:

  • Datatype
  • TypeConstructor
  • DataConstructor

[feature] `deepWalk`

Write test for each case.

  • try to write failing test that can be fixed by using deepWalk here.

[feature] coverage check

To support recursive function, beside termination-check we also need coverage-check.

The coverage-check of function clauses, can be implemented separately from the termination-check.

Solution 1:

  • Compute the max depth of all patterns in all clauses of a function.
  • Generate data up to the given depth.
  • Assert all generated data are covered by the clauses.

[DX] error report

We should setup an error report framework (and test it) as soon as possible.

  • ElaborationError might have span

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.