core-typed 2020-02-16

regarding that it would be challenging, i am mostly thinking of instead of storing the environment in a hash-map to store it in an in-memory datalog database (could be datascript) and just start with using the pull syntax to get items out, practically the same as for a hash-map. but once the environment is stored in that way, one would have the freedom to a) use datalog queries and rules selectively when a more complicated invariant is supposed to hold in the type environment and, independently, b) expose immutable snapshots of this environment also to the runtime code in case it declares its interest (intertwining compile and runtime more effectively).

datascripts motto is literally to make using datalog as easy as using a hash-map 🙂

(and as performant)

the goal is by no means to write the full type system in datalog. it is not expressive enough for that

fwiw I ported something like #lang functionality to clojure. kind of lost interest because I didn't feel there was much demand for it https://github.com/typedclojure/core.typed.lang.jvm

but I'm personally interested in preserving clojure's evaluation model as-is as much as possible, it certainly has it's advantages. very simple.

it breaks down when you need to write macro-generating macros. but that's the only limit I've come across in practice

and macros aren't that important in clojure anyway

yes, that is very different in racket.

do you have a sense of the parts of racket you would like to see ported over?

people here use redex a lot to prototype languages as it seems, i have not used it it yet

I'm a big fan of clojure. I'm not glamouring for anything in particular from racket. I want the best parts of Typed Racket and turnstile, but tailored precisely to clojure

anything that helps me understand clojure more deeply, I'm really into

and basically everything I've learnt has been from contrasting it with racket/typed racket. so I find racket useful and interesting from that perspective

sorry, not the right link

i mean "Dependent Type Systems as Macros" on this page, somehow it is not part of the URL

oh yea they finally got it published

this is an extension of turnstyle called turnstyle+

haven't read it yet

yes, i am meeting william several times a week in reading groups, we are going through his thesis at the moment

my wife worked on cur for a few months about a year ago

so I got to hear about some progress and their frustrations in publishing a previous version of that paper

basically reviewers saying "why isn't this agda"

and "this is only possible in racket => boring"

that's cool, is he presenting his own thesis?

hehe, the PL community is more partisan than the ML community even

we are sitting together and he is answering questions

we go through it chapter by chapter

"Since dependently typed languages may evaluate expressions while type checking, checking dependent types with macros requires new macrology design patterns and abstractions for interleaving expansion, type checking, and evaluation"

sounds familiar..

probably should read this paper

tho I like to see what I invent before seeing prior research

I get tunnel vision once i see a solution

I'm also juggling expansion, type checing, evaluation, and symbolic excution

but it's basically the same thing I imagine. Just some extra details of clojure thrown in

turnstile+'s "evaluation" is probably just dependent type checking, and for me it's literally calling eval on a clojure form

so my symbolic execution is turntile+'s evaluation (probably)

that makes sense. what would be necessary to make that extensible? i.e. being able to strengthen clojure semantics by adding annotations or additional derivations and being able to plug into your pipeline?

i am building bayesian inference schemes that propagate measures through your code. there can be facts you know about these numeric entities or that you can add to description of algorithms, e.g. about convergence or resource usage, that could be automatically available to the type system.

in a more commercial setting i imagine having world knowledge about the system and clients that are referred to in the types that might be provided through a database

that is what we have been discussing with our cloud service provider client. in that setting you want to ensure static guarantees over your distributed system and would like to type check your infrastructure

if the type information would be in something like a datalog database then this would be way easier

if you can then write down rules with queries on the environment instead of using the clumsy PL notation, you could build much more refined type judgements as extensions and maybe make dependent types more accessible

i can try to come up with more concrete examples, if this is still too vague

i think most type system people work with functional languages, but are amazingly primitive when they deal with the description of the logic on the type system level. they mostly use adhoc encodings to describe the rules

I love concrete examples

let's say you assign a memory limit to a client inside of your cloud system that you track in your client-related database. you also track the memory limits of all the docker containers you can spawn on the system with kybernetes. now you do runtime checks regularly to ensure that clients to do not violate their limit. nonetheless you write nontrivial code that does scheduling and cluster allocations and it would be nice if you could prove that it does not violate the memory limits provided to it in form of the database over clients and the database over cloud containers

with client here i mean business client

it is similar to the dependently typed example of checking shapes of arrays that are passed in at compile time and ensuring you do not access them out of bounds

i am not sure whether this was super clear

I'm with you I think, how does that tie in with your extensibility q?

what are you extending?

you can first collect and extract as much information as might be helpful in the database for the type environment and others and then right rules that make use of all this information

type inference and execution is kind of interleaved in dependent types

that means if you can extend your knowledge during execution by collecting information of the environment, proving certain things in a local scope becomes much easier

maybe i am oversimplifying

but i imagine having a kind of type checking be partially done at runtime, somewhat like gradual typing

where runtime checks are introduced, but they could also then run a refined type inference to make sure that everything is adding up

I have no idea how to plug dependent type checking into runtime clojure evaluation

do you have a typed eval?

and I guess that's the big distinction between my work and turnstile+? their evaluation is literally runtime?

probably not, what would that look like?

like, eval with an expected type?

my "evaluation" is symbolic

are you asking if typed clojure implements an interpreter?

i am not sure whether their evaluation is at runtime

hmm ok. I thought that's what dependent type checking meant

i am asking whether you could rewrite part of the code before it goes into eval

not well versed in it myself

i think so too, but i have to check more precisely what they do. we are not at turnstyle yet in the reading group, i have just heard about the paper a few weeks ago

yea you can emit custom code from a typing rule. but that's not a good idea because (unlike turnstile) core.typed isn't always in charge of expansion

which is why I dabbled in #lang's for clojure, to hook core.typed into load/require

well, if you used a typed #lang in clojure that always enforced type checking on load, it would be a good idea

and the extension points would be similar to turnstile's I imagine

to rephrase on a high-level, i think an extensible static analysis stack allows to join the type inference with a general proof system over a rich set of domains if the basis for the logical inference rules is a shared logic programming language like datalog

datalog is also used for reachability analysis and there are some attempts to use it for type systems, but in clojure land we also have our domain data in a powerful datalog database

(i.e. datomic)

what do you mean with extension points exactly?

watching their talk now

like you can define a typing rule for macro invocations and primitives

that's where you plug into the type checker

I'm not clear what exactly you want to "plug into my pipeline". the compilation of rules to datalog?

i think the rules themselves could contain datalog, it would actually make more complicated rules more explicit

at least i have found some of the notation changing between papers and confusing when the rules do tricky things

i mean the environment is effectively a database

sounds like occurrence typing where the environment is a set of propositions

at least it sits close to that in my brain

can you describe this position a bit more?

yea so instead of the normal type environment which is a sequence of mappings from var=>type [x : Int, y : Bool], you use propositional logic to represent the current environment. atomic propositions are statements of the form "x is of type t". and you can && and || them any way you like

like {"x is type Int", "y is type Bool"} is a proposition env

and you would query the env to find the type of x

{"x is type Int", "y is type Bool"} |- x : Int

and the rule for looking up in the type environment does constraint solving (model checking IIRC?) to determine the type of x

you can have interesting props like ("x is type Int" || "y is type Bool")

and then if you type check (if (integer? x) e1 e2) you can update the then branch with the prop "x is type Int", which reduces the env to "x is type Int", and the else branch with !"x is type Int" (negation) which reduces env to "y is type Bool"

check out "Logical Types for Untypable Languages" Tobin-Hochstadt & Felleisen for intro

also Andrew M Kent has a bunch of ideas simplifying the original paper

so this sounds like adding statements to a database

and then querying the database to get the type of bindings at a particular context

the intro/elim rules sounds similar

yes, that is very related, although Datalog itself provides a programming language to describe simple inference rules over relations extending on pure propositional logic. it is still first order though and some restrictions on mixing recursion with negation to stay terminating.

it would be like a base language for inference that can be extended by more rules, either in datalog or by ones doing more fancy logical constraint resolution

that would be useful for implementing occurrence typing. I tried using minikanren to do it once https://github.com/frenchy64/miniKanren-occurrence-type-inferencer

erm that link might be garbage, can't find the original

right. minikanren would be like prolog. the problem is that it does not necessarily terminate, so you could easily have an undecidable type system then

yea I had a hell of a time getting simple things to run quickly or even terminate

yes, that looks very much like the same line of thought

the very pragmatic benefit i see from using a datalog database, is that we know how to populate it from everywhere with information

what is your opinion about this direction of thinking?

don't know datalog. I like the direction of somehwere inbetween hand-written and minikanren

(or more precisely, datalog is compositional over multiple data sources, datahike for instance can join data from everywhere, locally, a cluster db or one running for another party on AWS)

i think you still need to be able to write custom inference logic, because type systems very much are at the boundary of making logic programming tractably enough to handle programs

yea. it sounds challenging. I g2g tho, chat later!

have a nice evening