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 ... 3 4 [5]
61
Ideas / Macros again
« on: October 20, 2018, 07:14:06 PM »
I just wanted to discuss some possible ways of doing it that I was playing with.

First, we have to consider macros as always expanding where they are referenced to keep it simple.

Code: [Select]
macro @foo(int v) {
  v++;
  if (v > 10) return 10;
  return v;
}
int a = 10;
@foo(a);

This code would then be exactly equal to:

Code: [Select]
int a = 10;
a++;
if (a > 10) return 10;

Macros simply expand in place.

Secondly, we can have macros returning values:

Code: [Select]
macro int @foo2(int v, int w) {
  v++;
  if (v > 10) return 10;
  w += 3;
  return 0;
}
d = 0;
a = 10;
int b = @foo(a, d);
[/mode]

This expands to:
[code]
a = 10
a++
int b;
if (a > 10) {
  b = 10;
} else {
  b = 0;
  d += 3;
}

Note that I'm using a sigil to indicate the code expansion. I think this is a good idea, even if @ collides with current C2 use and we need to pick another sigil. It makes it very obvious that macro expansion occurs.

We can allow the macro to take a body (yeah, I'm calling the type of the body "{}" it should be something better obviously!):

Code: [Select]
macro int @foo3(int a, {} body) {
   while (a > 10) {
      a--;
      @body();
   }
}

b = 20;
@foo3(b) {
  print(b);
}

We expand this to:
Code: [Select]
b = 20;
while (b > 10) {
  b--;
  print(b);
}

62
Ideas / char / int / i8 / i32 and so on
« on: October 20, 2018, 06:59:46 PM »
I talked a bit about readability for int/floats in another thread. Reading through the sample code, I notice that "char" is actually there as i8. Can we perhaps take a page from java and introduce named types with fixed sizes?

bool = u1
byte = u8
char = i8
short = i16
ushort = u16
int = i32
uint = u32
long = i64
ulong = u64
float = f32
double = f64

I suggest that the bit-named types still remain (so char is alias to i8, it doesn't replace it). This allows us to postpone naming of f128 and allows easy insert of middle sized types like i24 if that ever would be interesting.

I'm not entirely sure that this is a good idea, but I think that either keep it the bits explicit for everything (including char) or use well defined aliases for all basic types.

63
Ideas / Restricted pointers (and the analogue with threads)
« on: October 20, 2018, 02:42:27 AM »
In C we can now use "restricted" to declare that a pointer cannot be aliased. I will try to argue that the "restricted" should be default and you should need to explicitly have to declare a pointer as not restricted.

My experience after both writing correct threaded code and fixing incorrectly written threaded code is that attempts to create an illusion of "this is now thread safe" without having to actually understand threading is doomed. Well meant things like the keyword "synchronized" or so-called "thread safe" libraries (that actually still required you to understand threading to use it properly in a multi-threaded environment) are increasingly understood to be a bad thing. These are leaky abstractions that often just makes things worse (creating deadlocks etc)

I suggest a similar approach for C2. Basically say that "in C2 all pointers are considered restricted, so if you want to tell ensure the data is always loaded from memory, you need to explicitly mark it so". This is, incidentally, pretty similar to how volatile works, so the same keyword could actually be reused.

64
Ideas / Allocators and context
« on: October 19, 2018, 02:19:33 PM »
As is possibly well known, Jai uses a "context" that can be pushed / popped.

If the standard malloc and libraries then uses the context we gain some very powerful abilities.

For example, consider handling a web request (I'm going to use C syntax here)

Code: [Select]
int process_request(Request *request)
{ ... }

int handle_request(Request *request)
{
    ....
    Context *context = push_context();
    BumpAllocator allocator = BumpAllocator.create(MAX_MEM);
    context.allocator = allocator;
    int err = process_request(request);
    pop_context();
    allocator.release();
    return err;
}

That is we emulate the php memory allocator. :D

65
Ideas / Consider native string & map
« on: October 17, 2018, 11:19:58 PM »
This is a rather uncooked idea, just to explain that I only suggest this as some inspiration rather than saying it should go into the language.

I blogged about this: https://medium.com/@christoffer_99666/why-system-level-languages-are-considered-difficult-a-different-take-7ad0982369b

Where my point is that the pain point of using C/C++/Rust etc is usually the lack of ergonomics for arrays, maps and strings. I would say that the main gain in going to a high level language is not OO, but having a lot less boilerplate for these.

Note also that Go 1 only has 2 generic structures: the array and the map. Everything else is non-generic.

These are also the only things that you REALLY need generics for (everything else are "nice to haves")

By adding a native generic array (including a variable size one) and a map + "real strings" and you increase the ergonomics immensely for the non-critical parts of a project.

66
General Discussion / State of progress?
« on: July 14, 2018, 11:36:22 PM »
Is C2 really alive or is it put in suspended animation?

67
General Discussion / Struct "inheritance"
« on: June 24, 2018, 12:13:33 AM »
Taking a page from JAI, why not allow "struct includes":

Code: [Select]
type MyData struct {
    const char* name;
    State status;
}

type MyDataExtended struct {
    int32 foo;
    MyData data @(inline);
    ExtendedStatus extendedStatus;
}

MyDataExtended foobar;

// initialize foobar here
...
// Init done


Code: [Select]
printf("Value: %s\n", foobar.name) // Due to the @(inline) attribute.

func void MyData.parse(MyData* data) {
    // ...
}

func void randomizeData(MyData* data) {
  // ...
}

foobar.parse() // valid, equivalent to foobar.data.parse()
randomizeData(foobar) // valid, equivalent to randomizeData(foobar.data)

All of this is resolved during compile time, so this would not work for example:

Code: [Select]
func void funky(void *data) {
   randomizeData(cast<MyData>(data));
}

funky(cast<void>(foobar)); // Will not work as expected.
However, the code WOULD behave nicely if MyDataExtended did not start with the i32 field...

68
General Discussion / Why the module restriction on struct functions?
« on: June 22, 2018, 10:35:57 PM »
From the docs:

"struct-functions are defined in the same module as the struct (not necessary the same file!)"

Why this restriction?

69
Ideas / What about initialization in conditions?
« on: June 22, 2018, 05:33:25 PM »
A typical while looks like this:

Code: [Select]
i32 a = 10;
while (a > 0) {
    a--;
}

Often it's not really necessary to have the variable outside the while scope. We could support this syntax:

Code: [Select]
while (i32 a = 10; a > 0) {
    a--;
}

It would be equivalent to:

Code: [Select]
{
   i32 a = 10;
   while (a > 0) {
      a--;
   }
}

The same could be used for other similar statements:

Code: [Select]
// if
if (i32 a = foo(); a > 0) {
   // a is available here
} else {
   // a is also available here
}
// case
switch (Height h = getHeight(); h) {
   case LOW:     
   case MEDIUM:
      // can access "h" here
      break;
   case HIGH:
      // can access "h" here
      break;
}

Pages: 1 ... 3 4 [5]