Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - lerno

Pages: 1 [2] 3 4 5
16
Ideas / Switch proposal
« on: November 28, 2018, 12:27:25 PM »
Putting it here instead as a comment in a longer discussion

Here is the propsal:

Code: [Select]
switch (a) {
  case 1 |  // Using : instead of | is syntax sugar for case 1: goto next;
  case 2 |
  case 3:
    foo();  // With : we get a break;
  case 4 |
  case 5:
    bar();
    goto next; // If we want to execute a statement then pass to next.
  case 6:
    baz();
}

// The above in C:
switch (a) {
  case 1:
  case 2:
  case 3:
    foo();
    break;
  case 4:
  case 5:
    bar();
  case 6:
    baz();
    break;
}

Another possibility is |: or :|

Code: [Select]
switch (foo) {
  case 1|:
  case 2|:
  case 3:
     do_something();

Using | means a that some care must be taken if there is an expression of type:

case 1|2: (This is is compiled to case 3: or course, but I think it's reasonable to require ( ) on any constant expression that isn't a literal.

So case 1+2: would not be allowed, but case (1+2): is ok.

Alternatives to goto next would be:

Code: [Select]
case 4:
   foo();
   fallthrough;
 case 5:
   ...

 case 4:
   foo();
   goto case 5;
 case 5:
   ...

 case 4:
   foo();
   goto case;
 case 5:
   ...

 case 4:
   foo();
   continue case;
 case 5:
   ...

 case 4:
   foo();
   next;
 case 5:
   ...

 case 4:
   foo();
   next case;
 case 5:
   ...

 case 4:
   foo();
   nextcase;
 case 5:
   ...

An even more lightweight syntax uses | for fallthrough, leading to this uniform syntax look:

Code: [Select]
  case 4:
   foo();
  | case 5:
   ...

Code: [Select]
switch (a) {
  case 1:
  | case 2:
  | case 3:
    foo();  // implicit break here
  case 4 :
  | case 5:
    bar();  // Fallthrough here because the next starts with |
  | case 6:
    baz();
}

17
Implementation Details / Suppress warnings
« on: November 27, 2018, 02:57:12 PM »
Suppressing warnings should be easy to do on a file / func / statement.

In IntelliJ, annotations are used to suppress warnings on file / class / method level, but can be suppressed by statement with a comment as well, in this manner:

Code: [Select]
// noinspection unchecked
Map<String, List<String>> nameMap = (Map)result.get("names");

For Xcode / Clang, it's much more complicated. You push the current state with a pragma, disable a warning and then have to pop it later. Very ugly:

Code: [Select]
#pragma clang diagnostic push
#pragma ide diagnostic ignored "UnusedValue"
lSeek += file_info.size_file_comment - uSizeRead;
#pragma clang diagnostic pop

I'd like for C2 to have a very easy way to suppress warnings in the manner of IntelliJ's comments.

Something like this:

Code: [Select]
// A.
lSeek += file_info.size_file_comment - uSizeRead; // $ignoreunused$

// B.
lSeek /* $ignoreunused$ */ += file_info.size_file_comment - uSizeRead;

// C.
// $ignoreunused$
lSeek += file_info.size_file_comment - uSizeRead;

// D.
// {unchecked:warn_unused}
lSeek += file_info.size_file_comment - uSizeRead;

Other styles are possible as well. The same should go for other scopes:

Code: [Select]
// {unchecked:warn_unused}
func i32 foo() {
   ...
}

// {unchecked:warn_unused}
type Foo struct {
   ...
}

For file scope it should be slightly different to avoid parsing ambiguity.

18
General Discussion / Discussions where?
« on: November 25, 2018, 11:50:11 PM »
Github issues, this forum or emails? What's the best place for feature suggestions and other ideas for improvement? I note that I'm writing all over the place and maybe it would be best to stick with Github issues?

19
C++ allows nested namespaces, which means we can have foo::bar::baz() (in C++). For C2, will modules always be single level?

For example if one encounters foo.bar.baz(), can I then be sure that foo is either the module name or the name of a variable defined in the local module – or imported as local?

And can I be sure that bar here can never be part of a module name?

I'm pretty sure that this is true right now, but what about the future – are any future ideas that could change this?

20
General Discussion / Overwriting fields in init struct.
« on: November 18, 2018, 04:11:57 PM »
In this article:

https://lwn.net/Articles/444910/

The following method is discussed for setting better defaults of vtables than having NULL in C for the Linux kernel:

Code: [Select]
#define FOO_DEFAULTS  .bar = default_bar, .baz = default_baz
struct foo_operations my_foo = { FOO_DEFAULTS,
  .bar = my_bar,
};

The usefulness here is that having a meaningful default method, the test for NULL can be avoided. So instead of:

Code: [Select]
if (my_foo.bar != NULL) my_foo.bar();

We can simply use:

Code: [Select]
my_foo.bar();

Since the default method is assumed to be correct for the situation.

Currently in C2, this would not be possible. While I understand the need to "error proof" things, I think this should not be forbidden in C2, and instead produce a warning that can be supressed using an @(override), like this:

Code: [Select]
#define FOO_DEFAULTS  .bar = default_bar, .baz = default_baz
Foo_operations my_foo = { FOO_DEFAULTS,
  .bar = my_bar @(override),
};

OR by setting a @(weak) on the default:

Code: [Select]
#define FOO_DEFAULTS  .bar = default_bar @(weak), .baz = default_baz @(weak)
Foo_operations my_foo = { FOO_DEFAULTS,
  .bar = my_bar,
};

22
Ideas / Allow compile time variables (Part of macro proposal)
« on: November 16, 2018, 11:31:12 AM »
I suggest the introduction of macro compile time variables, prefixed with the sigil $. These can only hold compile time values and are evaluated top down.

This is a variant of what already exists in C, but in a syntactically more friendly way.

For example this would be ok:

Code: [Select]
macro swap(a, b) {
  $x = typeof(a);
  static_assert(typeof(b) == $x);
  $x temp = a;
  a = b;
  b = a;
}

The example above is a bit contrived as in the above example we could simply have:

Code: [Select]
macro swap(a, b) {
  static_assert(typeof(b) == typeof(b));
  typeof(a) temp = a;
  a = b;
  b = a;
}

But still, it serves as an example on how to use it.

23
Ideas / Require "type" where type is used outside of declarations.
« on: November 16, 2018, 11:22:26 AM »
For example, instead of

Code: [Select]
sizeof(Foo)
sizeof(a)
sizeof(i32)

Require

Code: [Select]
sizeof(type Foo)
sizeof(a)
sizeof(type i32)


24
Implementation Details / Defer
« on: November 16, 2018, 01:35:18 AM »
After several nights of work I'm finally done with defer  ;D One big leap for simpler resource management.

Here's hoping it will be accepted folks!  ;D

25
Implementation Details / LLVM/C gen
« on: November 15, 2018, 03:27:49 AM »
The two backends makes it a bit hard to keep feature parity of both. LLVM is far behind, but what is the strategy?

Using C, a nice thing is that we can start bootstrapping early if we'd like to(!) We can build parts of the server in C2, then compile to C and then automatically copy that code into the main source!

On the other hand, keeping the same behaviour between LLVM and C isn't easy. I've looked at Clang's LLVM gen, and it produces a lot of optimized code by leveraging intrinsics for certain "known" functions. So for example, if Clang sees sqrt, it can swap the normal library version for a LLVM intrinsic. To complicate things further, those are target dependent :( So there are *massive* amounts of work to do – on the LLVM gen.

Obviously if we get more people behind the project then that might be an easier thing to do. Without a lot of people spending time on C2 it will have a hard time being anywhere near optimized.

So what would the plan be?

26
General Discussion / C2x
« on: November 14, 2018, 01:49:03 AM »
Very important to look at and incorporate: https://gustedt.wordpress.com/2018/11/12/c2x/

27
Ideas / Vtables and similar ”OO”-ish concerns
« on: November 12, 2018, 06:13:20 PM »
I stumbled over this (old) article:

https://lwn.net/Articles/444910/

This is about various OO-like constructs in the Linux kernel. I think it’s important to have a discussion on how to facilitate this in C2 without sacrificing low level predictabilty over layouts, sizes etc.

Follow up here: https://lwn.net/Articles/446317/

28
General Discussion / "Code of least surprise"
« on: November 08, 2018, 03:37:54 PM »
I think the one of the best features of C (which it shares with languages like Pascal, and in some sense Java) is that it's very clear from the code what is happening. The only thing that breaks the rule is macros.

Contrast to that to a language that is the complete opposite: Swift. In Swift, you can express opaque DSLs trivially. Overloading on return type is pretty crazy, as is the implicit conversions of C++.

I would call C a language with "code of least surprise" – what you see is what you get. If you analyse a few lines of code you can actually directly know how the execution will flow, what types variables are etc, instead of things happening implicitly "behind the scenes".

My understanding is that C2 is pretty much the same: as far as it possible no unseen, implicit code that works behind the scenes creating surprising effects (Swift, C++). If so, maybe state explicitly it in "philosophy"?

29
Ideas / Tagged unions
« on: November 07, 2018, 01:14:15 AM »
On github Rust's enums were mentioned, and that they're essentially tagged unions.

Several languages that offer unions also have tagged unions "out of the box".

Borrowing from Cyclone a bit, consider this:

Code: [Select]
tagged union Foo {
  int i;
  const char *c;
};

Foo foo;
foo.i = 3;
@istag(foo.i) // => true
@istag(foo.c) // => false
foo.c = "hello";
@istag(foo.i) // => false
@istag(foo.c) // => true

switch(@tag(foo)) {
  case Foo.i: printf("Was %d\n", foo.i); break;
  case Foo.c: printf("Was %s\n", foo.c); break;
}

The code is a variant of what Cyclone and Rust does.

Note that I use the @-prefix for the compile-time keywords. If we decide on not having a @-prefix, then tag / istag would need to be keywords.

30
Ideas / Generics of Cyclone
« on: November 07, 2018, 12:57:48 AM »
Cyclone has generic types, called datatypes, they are used in this manner:

Code: [Select]
  datatype T {
      Integer(int);
      String(const char *@fat);
    };

    datatype T.Integer x = Integer(3);
    datatype T.String y = String("hello, world");

    void printT(datatype T@ a) {
      switch (a) {
      case &Integer(i): printf("%d",i); return;
      case &String(s): printf("%s",s); return;
      }
    }

I'm not making a proposal to add it, merely something that would be useful to discuss.

Pages: 1 [2] 3 4 5