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
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?

17
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?

18
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,
};

20
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.

21
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)


22
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

23
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?

24
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/

25
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/

26
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"?

27
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.

28
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.

29
Implementation Details / Code formatting of C2's c++
« on: November 05, 2018, 07:59:56 PM »
This might seem like a minor issue, but wading through thousands of lines of Clang (I've cut away in excess of 30,000 lines of code), there are two coding habits that makes the code IMMENSELY hard to read.

One is single line if's:

Code: [Select]
if (foo)
  do_something();

This obviously is even worse when adding else as well. The problem here is when you try get an overview of  a function. Here K&R + single statement on two lines is making something really horrid:

Code: [Select]
namspace foo {

/* many lines of code */

  void a_method() {
  /* MANY lines of code */
    do_struff();
    if (foo)
      do_something();
  } // <- What ends here??

/* more lines of code */

} // <- What ends here???

Basically it's hard what block ends where.

I prefer (1) single statements ifs ALWAYS on a single line, Allman style. Any of those would solve the problem, BOTH is best:

ALLMAN
Code: [Select]
namspace foo
{

/* many lines of code */

  void a_method()
  {
  /* MANY lines of code */
    do_struff();
    if (foo)
      do_something();
  }

/* more lines of code */

}


K&R Single line:
Code: [Select]
namspace foo {

/* many lines of code */

  void a_method() {
  /* MANY lines of code */
    do_struff();
    if (foo) do_something();
  }

/* more lines of code */

}

ALLMAN single line:
Code: [Select]
namspace foo
{

/* many lines of code */

  void a_method()
  {
  /* MANY lines of code */
    do_struff();
    if (foo) do_something();
  }

/* more lines of code */

}

I understand most have a preference for K&R, so I'm not going to fight for Allman. But that two line single statement is a killer.

Switch-case where "case" does not have indention is difficult for similar reasons, although the two line if is by far the worst.

30
Ideas / Does C2 support this? Otherwise it should. "Labels as values"
« on: November 05, 2018, 06:35:38 PM »
For some problem domains, this can be extremely effective:

https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

Pages: 1 [2] 3 4 5