Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Fix up dependent contract syntax #8

disnet opened this Issue · 10 comments

4 participants

Tim Disney Paul Callaghan Paul Miller Tobiasz Cudnik
Tim Disney

I'm not too happy with the syntax we have for dependent contracts right now.

f :: (Num) -> !(result) -> $1 > result

Scope of $1 is not obvious and its a bit to magical. Would love to allow explicit naming:

f :: (arg:Num) -> !(result) -> arg > result

But this conflicts with object contracts (and I don't think this can be disambiguated). Some other ideas that have been bouncing around:

f :: (x::Num) -> !(result) -> x > result
f :: (x=Num) -> !(result) -> x > result
f :: (Num as x) -> !(result) -> x > result
Paul Callaghan


+1 on explicit naming.

can you give some concrete examples of where object contracts conflict? or say which rules conflict? I know some LALR tricks which might (or might not) help.


Paul Miller

What about using Haskell syntax for this?

f :: (Num x) => x -> !(result) -> x > result
Paul Callaghan

perhaps a better question is: what syntax do you use for each in your papers?

Paul Callaghan

ie, if it's not obviously conflicting in your papers, then it's a shame to let LR dictate it.

Tim Disney

The problem isn't just disambiguation. It's that the syntax I'd love (and see most often in papers) where we name the argument like name:Num is exactly the same as an object contract (since CoffeeScript lets us have implicit braces). I don't think we want to change how object contracts are handled in the contract language so we have to do something else.

@paulmillr I think that syntax would be a bit confusing since in haskell that means to constrain by the typeclass right? Humm...maybe that'd work though. The multi arg would look like:

f :: (Num x, Str y) => (x, y) -> !(result) -> x > result and y > result

Or simpler since => is redundant:

f :: (Num x, Str y) -> !(result) -> x > result and y > result

But now x and y look like type variables instead of just names so probably not what we want.

I think my favorite syntax right now is (Num as x) -> !(result) -> result > x. Thoughts?

Paul Miller

Your "typeclass as var" proposition seems to me as good as haskell example.

Or simpler since => is redundant:

I don't think so: consider a function where we pass many similar arguments:

f :: (SomeLongClassName s, SomeLongClassName2 t) => (s, s, s, t) -> [t, s, t, s] -> t s s s
# or
f :: (SomeLongClassName as s, SomeLongClassName2 as t) => (s, s, s, t) -> [t, s, t, s] -> t s s s

What would this example look like without =>?

Tim Disney

That syntax wouldn't work for dependent types. The point is to name each parameter uniquely.

What you have might actually be useful as a kind of "contract variable" but we need something different for uniquely identifying each param. We could combine them:

f :: (SomeLongClassName s, SomeLongClassName2 t) => (s as arg1, s as arg2, s, t) -> !(result) -> arg1 > arg2 > result

But if we just want a way to alias long contract names there's already a way since contracts are just values:

s = SomeLongClassName
f :: (s, s as arg2) -> ...

Not sure if it's a good idea to introduce special syntax for this.

Paul Miller

```s = SomeLongClassName
f :: (s, s as arg2) -> ...

This solution is OK then. So, I think the form f :: (s, s as arg2) -> ... is great (with no support for dependent types).

Tobiasz Cudnik

Why overcomplicate simple things? If return from 1st func is a param to the 2nd one, same the params of the 1st one should be. Like so:

    f :: (Num) -> !(result, params) -> params[0] > result

Using named params (Num as x) is harder to maintain, because you can define 2nd function as generic one and use it with many others. Then, you would have to maintain same param name in all of these functions.

Tim Disney

Ha! Yeah you're right, that does simplify things a bit.

Realized we have a bit of an ambiguity though. A dependent contract:

f :: (Num) -> !(res, params) -> params[0] > res

Not a dependent contract:

MyEven = (x) -> x % 2 is 0
f :: (!MyEven) -> !MyEven

! is overloaded here.

Tim Disney disnet closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.