hoshino9 / HoshiNoMagic

Other
1 stars 0 forks source link

Tracking Issue for Type #13

Open HoshinoTented opened 2 years ago

HoshinoTented commented 2 years ago

Built-in Types

~t          ** reference type of t
i8, i16, i32, i64         ** integer with the corresponding size
f32, f64  ** floating with the corresponding size
int          ** alias of i32
string     ** string (old name: lang) non-keyword
char       ** char (old name letter)
logic       ** boolean non-keyword

Type Declaration

box some_type {
    field0: lang,
    field1: i32,
    ** and so on
}.

** or

box another_type { lang, i32 }

Usage

box foo <- some_type { "123", 1 }.
box foo1 <- some_type { field0: "123", field1: 1 }.
box bar <- another_type { "123", 1 }.

Generics Type Declaration

box type_name [p1 ; p2 ; p3 ... ] {
  ** ...
}.

Usage

box foo <- type_name [t1 ; t2 ; t3 ...] {
  ** the same as the non-generic type
}
HoshinoTented commented 2 years ago

if our lambda syntax is:

box lambda <- { a; b; c ->
    ** do something
}.

then I am happy to use this syntax as generics syntax:

box { t; s; r ->
    field_t: t,
    field_s: s,
    field_r: r,
}: some_type.

However, Kotlin's lambda syntax is pretty, but I want to differ from it.

HoshinoTented commented 2 years ago

why not:

box [a; b; c] {
   ** ...
}: some_type.
HoshinoTented commented 2 years ago

idea from coq: if the compiler is unable to infer a type for some type parameter, developers can just specify a type for that type parameter (but not all), like:

** foo: [a; b; c; d][a; b; c] -> d
** foo[1; 2; 3]. the compiler can not choose a type for the type parameter 'd'

foo[d <- i32][1; 2; 3].
** or
foo[_; _; _; i32][1; 2; 3].
HoshinoTented commented 2 years ago

the arguments for one magic have two parts: type parameter and normal parameter. for example:

magic foo[i: i32] {
    i
}: i32.

** foo has a singature: [i32] -> i32
** it is equivalent to [][i32] -> i32, the type parameter list is empty

magic bar[a][i: a] {
    i
}: a.

** bar has a signature: [a][a] -> a.
** first 'a' is the name of the type parameter, the second one is the type of parameter.
HoshinoTented commented 2 years ago

idea from coq: if the compiler ...

for the sake of simplicity, we can only support the second one.

HoshinoTented commented 2 years ago

why not:

box [a; b; c] {
   ** ...
}: some_type.

I prefer this version, box [a; b; c] {}: some_type. is similar to the magic declaration, and type declaration is a magic on type: accepts type as its parameter and returns a type!

HoshinoTented commented 2 years ago

But the empty space between the box keyword and the Type Parameter list is weird.

HoshinoTented commented 2 years ago

I forgot...

Use this instead.

box some_type [a; b; c] {
  ** ...
}.

If : some_type is the return type then it should be a type of type.

HoshinoTented commented 2 years ago

What is the syntax of member magic?

HoshinoTented commented 2 years ago

What is the syntax of member magic?

I think I will use a rust-like way...

HoshinoTented commented 2 years ago

Enumerate Structure:

box option [a]
  | some { value : a }
  | none

In fact, I want to make this OCaml-like syntax more HNM-like:

box option [a] {
  | some { value : a } 
  | none

  ** or (the beginning "|" is optional)
  some { value : a } | none
}.

or

box option [a] <- some { value : a } | none.    ** This looks like a variable declaration, which is ambiguous.
                                                                        ** Again, the beginning "|" is optional.

Pattern Matching would like:

match (some_option) {
  ** Optional beginning "|"
  | some { value } => ... 
  | none => ...
}

** or

match (some_option) {
  | some { value: v } => ...
  | none => ...
}

Non-exhaustive matching is now allowed.

HoshinoTented commented 2 years ago

Concept (aka Trait):

concept concept_name [ type_parameters ] {
  ** `concept` keyword can be simplified to `con`

  magic magic_in_concept [ ... ] [ ... ] -> ...

  magic magic_with_default_impl [ ... ] [ ... ] { ... }: ...

  ** a magic with self is similar to the Rust one, however, there is no ownership in HNM, so `self` impleis copy, `~self` implies referencing
  magic magic_with_self [ ... ] [ self ; ... ] -> ...
}.

Impl Concept:

** use `Concat` keyword
concat concat_name [ type_parameters ] {
  ** `concat` keyword can be simplified to `nya`
  ** concat_name can be omitted
  ** implementations...

  magic magic_in_concept [ ... ] [ ... ] { ... }: ...

  ** no need to impl a magic that has a default implementation

  magic magic_with_self [ ... ] [ self ; ... ] {
    ** self has type: type_name [ ... ]
  }: ...
}: type_name [ ... ] -> concept_name [ ... ].

Concat is a connection between types and concepts, this syntax provided the possibility of multi-implementation between the same type and the same concept.

If the compiler found only one Concat or the concat name was omitted, that Concat was used. If there is an unnamed Concat, then Multiple Concat is disallowed.

Multi-Impl

area natural.

con say_hello {
  magic hello [ self ] -> unit.
}.

nya concat1 {
  magic hello [ self ] {
    natural->emit["Hello: " + self->to_string[]].
  }.
}: i32 -> say_hello.

nya concat2 {
  magic hello [ self ] {
    natural->emit["Hi: " + self->to_string[]].
  }.
}: i32 -> say_hello.

magic center [] {
  box i <- 1.

  ** i->hello[].  ** Compile error. There are multiple concats of i32.
  concat1[i]->hello[].  ** print "Hello: 1"
  concat2[i]->hello[].  ** print "Hi: 1"
}
HoshinoTented commented 2 years ago

con sounds like a Kitsune and nya sounds like a Neko.

HoshinoTented commented 2 years ago

The Concat Syntax is not friendly to IDE, we have to write the "return type" first for the ide prompt

HoshinoTented commented 2 years ago

Scopes

box type_name [ type_parameter_scope ] {
  ** type scope
  constructor0 { 
    ** constructor scope
  }
}

Type Scope

Available Syntax

Constructor Scope

Available Syntax

HoshinoTented commented 2 years ago

The syntax like xxx {}: ttt. limits coding habits, it encourages people writing it in (the underline is the focus):

xxx {}: ttt_

then (moving focus):

xxx {_}: ttt

finally (inserting a new line):

xxx {
_}: ttt

This is interesting, I didn't think about these anytime. However, I think this is good.