Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested structs and functions within structs #72

Open
1 of 3 tasks
ballercat opened this issue Jan 28, 2018 · 7 comments
Open
1 of 3 tasks

Nested structs and functions within structs #72

ballercat opened this issue Jan 28, 2018 · 7 comments

Comments

@ballercat
Copy link
Owner

ballercat commented Jan 28, 2018

Goal

Allow for nested structs and functions within structs.

Overview

Depends on (#28)

Closures are cool, but to be useful you'd want to return an object/struct with a closure or another struct as a field.

Basically, this syntax should be possible

type lambda Closure = () => i32;
type Struct = {
   increment: Closure,
   decrement: Closure
};
function getActions(): Struct {
  let x: i32 = 0;
  const result: Struct = 0;
  result = {
     increment: (): i32 => { 
        x += 1;
        return x;
     },
    decrement: (): i32 => {
        x -= 1;
        return x;
    },
    getX: (): i32 => { return x; }
  };
  return result;
}

export function test() : i32 {
  const actions: Struct = getActions();
  actions.increment();
  actions.increment();
  actions.decrement();
  // should be 1
  return actions.getX();
}

This should make the syntax much more expressive and allow for a wide range of applications.

Acceptance Criteria

  • Allow nested struct types within other structs
  • Allow closure types within structs
  • Test everything
@iddan
Copy link

iddan commented Feb 8, 2018

Why using the lambda keyword?
In TS & Flow the syntax is:

type Closure = () => i32;

@ballercat
Copy link
Owner Author

@iddan

It's easier to compile this way.

@iddan
Copy link

iddan commented Feb 8, 2018

I assumed, but I think that introducing a new keyword is problematic. Maybe this can be solved with a special generic?

@ballercat
Copy link
Owner Author

How would a generic function type work for this? Could you be more specific, what syntax would be an alternative?

For background, I initially did use regular functions types for closures, but the two have fundamentally different representations in the binary. This means that syntax becomes ambiguous, where a function, for example, can return either a closure or a function pointer. By extension, any use of a return value from a function like this is now also ambiguous.

All this means is that types have to be specific to the thing they represent. If there is a way to express a closure being different with existing syntax, I'm all for it though.

It also may be possible to omit the lambda keyword in the future, but I won't fix this until we are well on our way to a 1.0.0 release. Unless someone puts up an MR to resolve the ambiguity I described above.

@iddan
Copy link

iddan commented Feb 8, 2018

You can mark external functions explicitly:

-type Log = (i32) => void;
+type Log = External<(i32) => void>;

@ballercat
Copy link
Owner Author

Cool, so are you suggesting that we should have a built-in type for Lambda instead of a keyword? That could work I think with something like this

-type lambda Closure = () => i32;
+type Closure = Lambda<() => i32>;

or

-type lambda Closure = () => i32;
+type FunctionType = () => i32;
+type Closure = Lambda<FunctionType>

I personally have not seen this particular use of generics before, but this could work. Would need a type parser change/PR but I like it 👍

@Chamberlain91
Copy link

Chamberlain91 commented Jul 24, 2018

Might I also suggest replacing the 'type' keyword for 'lambda'. For example 'lambda Func = () => i32’

Note: I'm on my phone and I'm unsure how the syntax style formatting works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants