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.


Messages - lerno

Pages: 1 ... 5 6 [7] 8 9 ... 17
91
Ideas / Re: Function inside function
« on: November 14, 2018, 06:30:42 PM »
This C feature is only in GCC/Clang or?

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

93
Ideas / Re: One more big thing: Errors
« on: November 13, 2018, 08:47:33 PM »
My guess was that it wouldn't need to add much complexity. But the idea has to be completely fleshed out before knowing for sure. A comfortable and practical syntax is also necessary.

94
Ideas / Re: Enum improvements
« on: November 13, 2018, 08:46:26 PM »
It's more of a practical question. If there are struct constants, then we can emit those additional ones during enum generation. It feels like there are less "special cases" if it's like that. I don't think people will add lots of enum constants...

95
Ideas / Re: Keyword "func" - redundancy?
« on: November 13, 2018, 08:43:33 PM »
It's used in a several languages. I think I prefer func.

96
Ideas / Re: Naming restrictions
« on: November 13, 2018, 08:41:33 PM »
So what about it, should we use it during parsing? That way we can skip some steps during analysis.

97
Ideas / Re: [Email suggestion No. 3] type casts in C2 + bugs
« on: November 13, 2018, 08:39:28 PM »
Look at the examples here: http://www.c2lang.org/forum/index.php?topic=108.0

I ended up with these possibilities:

a. cast(foo as i32)
b. cast(foo, i32)
c. foo->i32
d. (foo:i32) alt. cast(foo:i32)
e. (foo::i32) alt. cast(foo::i32)
f. foo.as(i32)
g. foo :> i32

Exactly because we want to avoid the difficulty of parsing the suffix there. That's my main reason for abandoning my suggestion of "foo as i32"

I think (foo:i32) is pretty radical but nicely terse. The only objection for me is that the parsing might be iffy.

Any "cast" version is very old fashioned but safe as alternatives.

Let's consider 2 common situations:

Code: [Select]
double f = (double)(3 + (unsigned)foo());
Bar bar = bars[(size_t)i];

Here's what they'd look like:

Code: [Select]
d64 f = cast((3 + cast(foo() as u32)) as d64);
Bar bar = bars[cast(i as size_t)];

Code: [Select]
d64 f = cast(3 + cast(foo(), u32), d64);
Bar bar = bars[cast(i, usize)];

Code: [Select]
d64 f = (3 + foo()->u32)->d64;
Bar bar = bars[i->usize];


Code: [Select]
d64 f = (3 + (foo():u32)):d64);
Bar bar = bars[(i:usize)];

Code: [Select]
d64 f = cast(3 + cast(foo():u32)):d64);
Bar bar = bars[cast(i:usize)];

Code: [Select]
d64 f = (3 + (foo()::u32))::d64);
Bar bar = bars[(i::usize)];

Code: [Select]
d64 f = cast(3 + cast(foo()::u32))::d64);
Bar bar = bars[cast(i::usize)];

Code: [Select]
d64 f = (3 + foo().as(u32)).as(d64);
Bar bar = bars[i.as(usize)];

Code: [Select]
d64 f = cast((3 + (foo() :> u32)) :> d64);
Bar bar = bars[(i :> size_t)];

98
Ideas / Re: Vtables and similar ”OO”-ish concerns
« on: November 13, 2018, 08:26:11 PM »
How do we facilitate these constructs in C2?

I've been thinking something along the lines of:

Code: [Select]
type Foo interface {
  void foo($Foo foo);
  void bar($Foo foo);
}

type X struct {
  i32 a;
  i32 b;
}

type Y struct {
  i32 a;
  i32 b;
}

func X.foo(X* x) { ... }
func X.bar(X* x) { ... }

func Y.foo(Y* x) { ... }
func Y.bar(Y* x, i32 z) { ... }


func void getFoo($Foo a)  // <- Use a sigil to indicate that this is NOT a struct!!!
{
   a.foo();
   a.bar();
}

X x;

$Foo foo = $Foo(&x);
$Foo foo2 = $Foo(&y) // ERROR!

getFoo(x); // Fine! (Implicit wrap)
getFoo(y); // BAD

Possible extension, optional methods:

type Foo2 interface {
  void foo($Foo foo);
  void bar($Foo foo) @(optional);
}

func void doFoo($Foo a)  // <- Use a sigil to indicate that this is NOT a struct!!!
{
   a.foo();
   if (a.bar?) a.bar();
   a.bar?(); // Call if a.bar() exists.
}
[/code]

I'm envisioning something like this:

interface $Foo defines a struct like this:

Code: [Select]
struct __interface_Foo {
  uint32_t identifier;
  uint32_t bitfield; // 1 has optionals, rest is available
  void (*foo)(void *);
  void (*bar)(void *);
  uint8_t[] optionalBitmap;
}


The last part is obviously if we have optionals. The point here would be to avoid having to retrieve the function pointer to see if it's implemented or not, instead the corresponding bit is checked. This avoids a load från L1/L2.

A $Foo "object" looks like:

Code: [Select]
struct {
  void *instance;
  struct __interface_Foo *interface;
}

This should be very similar how Go does it.

There are some outstanding questions to this:

  • How is memory handled? If I want to free a list of $Foos, can I do so, or do I need to free the underlying pointer?
  • Can I directly create a $Foo of X, or do I need to wrap the X (like in the example)
  • Is it fine to just structurally adopt $Foo on the fly, or do we want a much more rigid system?
  • Can the syntax be simplified?
  • What pieces does this hook up to?
  • Can we cut away more "magic"

I am not entirely sure that this should be in C2, but I think it's worth exploring quite a bit.

99
Ideas / Re: Dynamic arrays & fixed arrays
« on: November 13, 2018, 10:36:00 AM »
The main motivation for fixed arrays is safety and convenience though.

100
Ideas / Re: Dynamic arrays & fixed arrays
« on: November 13, 2018, 03:23:30 AM »
Absolutely, I raise these questions early so that there's plenty of time to get a decent proposal and then figure out if it's useful for the language.

And that order is important too:

1. Try to see how a proposal ideally would look like.
2. Using that final proposal – figure out if it's good for C2.

I think something that happened with some proposals for Zig that I made, was basically people threw things out judging from a very rough proposal. And I think that's a bad process of making improvements, because in the process of refining a proposal of a feature X, there might be better ideas emerging that uses some of concepts in X.

I mean, I read up on improvements in Rust, Go, Zig, Jai, Nim, Kit etc. Obviously ideas in there can't be imported into C2 as they are. So it would be a direct "no" for most of the features in those languages. But if you start looking there are parts that could be changed into something useful, or a subset that is simple and direct enough to fit C2.

So anyway, "how would dynamic arrays look like for C2?" and how would fixed arrays look? What sort of compatibility with naked arrays would we get etc. Usually digging into these details will make a lot of ideas go away by themselves :D

101
Ideas / Re: Tagged unions
« on: November 13, 2018, 03:14:00 AM »
But it creates a lot of boilerplate not to have it. It's a feature of lots of earlier languages. Pascal, Modula-2, Ada had them (for example) too.

I really understand the need not to have unnecessary stuff, but boilerplate must be removed as well. If you look at the Stmt classes - those are tagged unions and there is a (boilerplate) method to look at what type it is (is it type X?) and if so, allow it to be cast into that particular type.

Look at the many examples here: https://en.wikipedia.org/wiki/Tagged_union

If you look at Pascal, the discriminator tag is very explicit:

Code: [Select]
type shapeKind = (square, rectangle, circle);
     shape = record
                centerx : integer;
                centery : integer;
                case kind : shapeKind of
                   square : (side : integer);
                   rectangle : (length, height : integer);
                   circle : (radius : integer);
      end;

Something similar could be a minimal C2 extension:

Code: [Select]
type enum ShapeKind {
  SQUARE,
  CIRCLE,
  RECTANGLE
}

type Shape struct {
  i32 centerX;
  i32 centerY;
  ShapeKind kind;
  union (kind) {
    case SHAPE:
      i32 side;
    case RECTANGLE:
      i32 length, height;
    case CIRCLE:
      i32 radius;
  }
}

This should be iterated a few times

Code: [Select]
type Shape struct {
  i32 centerX;
  i32 centerY;
  i8 kind; // Just like this? Have the enum be implicitly created?
  union (kind) {
    square: { i32 side; }
    rectangle: { i32 length, height; }
    circle: { i32 radius; }
  }
}

It removes some with manual tagged unions:

1. Boilerplate is removed
2. The tag is explicitly linked to the union - good for code reading.
3. It has automatic update of the tag when accessing union fields, this removes a source of errors.
4. The compiler can analyse and make better warnings.
5. In the debug builds, the compiler can insert a check to warn when a union field is accessed when the type is different.

Note that everything can be done extremely straightforward here. The only "magic" is the dual update of tag and union value during write (shape.radius = 10 makes the shape a circle). Even that can be dropped actually. I think the most important parts are 1, 2, 4, 5. The uses of automatic tag updates can definitely be questioned.

102
Ideas / Re: Relax variable initialization rules
« on: November 13, 2018, 12:15:03 AM »
Oh, then I think I misunderstood.

103
Ideas / Re: Switch statement
« on: November 12, 2018, 10:25:39 PM »
I rather think that fallthrough is bad because it's so long to type :P

104
Ideas / Re: Variable's name unambiguity
« on: November 12, 2018, 10:23:23 PM »
Sigils and namespacing are two options. Personally I almost never run into the problem you write about. Shadowing variable names is something I have a warning on. I don't remember if C2 made it a warning or error.

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

Pages: 1 ... 5 6 [7] 8 9 ... 17