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

Pages: [1] 2
1
Ideas / Re: Function inside function
« on: November 09, 2018, 11:44:55 PM »
If it has visibility of local variables, then we are talking about a closure rather than a function and when you want to have closures in your language, you need to be wary of many factors, for example:

  • Do you clone the values of the local vars as they were when the closure was created?
  • Do you keep a reference or move them into the closure?
  • Can the closure be freed? If so, how? You probably wouldn't want a memory leak

Solving these is probably beyond the scope of this language.

2
Ideas / Re: What about initialization in conditions?
« on: November 09, 2018, 11:31:17 PM »
This is a bit similar to the Rust while-let construct, if we don't mind the patterns as C2 might never have those:

Code: [Select]
while let Some(i) = val {
        // ...
}

In C2, I imagine that the example:

Code: [Select]
while (Height h = getHeight()) {
  ..
}

Should just compile to:

Code: [Select]
Height h;
while (h = getHeight()) {
  ..
}

And I would say that's it. No separation, no other behavior, just something simple as this, so that too much new syntax isn't introduced and the complexity doesn't go up

3
Ideas / Re: Naming restrictions
« on: November 09, 2018, 11:25:48 PM »
I would much prefer it being a warning rather than a hard error (for reasons of FFI), but I agree with Bas that clear style is extremely beneficial, especially if you look at how horrible C look, where people use all sorts of indentation styles, naming schemes (especially juicy is some peoples' tendency to append _t to their types, which is a suffix belonging to POSIX only) and casing, which can result in a plenty of inconsistencies.

4
Ideas / Re: Keyword "inline" - [in lieing] ? :)
« on: November 09, 2018, 11:20:46 PM »
Keyword "inline" has sound like [in  lieing] (gerund of verb "lie") :) . We have to be careful with everything what Stroustrup invented.

The gerund of lie is lying. It's in an irregular verb :D but I see what you mean and I like your jokes. I actually think that inline was first in C or,  who knows, maybe even in some assembly extension, but it's fine, we need to be careful about Stroustrup indeed :D

5
Ideas / Re: Why "recipe.txt" ? :)
« on: November 09, 2018, 11:11:39 PM »
Why "recipe.txt" ? :) This name has bad assosiation with doctor (which knows better what is better for him you).

Maybe, "assembly.txt" is better?

The word you are looking for is prescription. Are you perhaps a slav? We use the same word for prescription and recipe here.  ;D

Haha my association with recipe was cooking. Like a cooking recipe to make cake. It describes the steps
needed to make something. Associating a thing with cake is of course better than associating with a docter ;).


I am hoping for the day C2 gets into electronic oven software and will be able to bake real cakes  :D

6
Ideas / Re: Keyword "func" - redundancy?
« on: November 09, 2018, 11:08:21 PM »
@acbaile If you used SML, it would be even funnier, because the keyword there is just fun  :)

I agree about the keywords. Another point is that even though they might seem redundant, they make it easier to read for humans as well. The moment you see the keyword, you immediately know what you are dealing with, as opposed to having to read the whole line (or more). The difference is tiny, but it is still there, I'd say.

On the topic of variable keyword, I'd say it depends on the language. In languages Rust, SML, OCaml and Reason, that have some form of type inference, the let or val keywords work pretty well. The line is shorter, clearer and tells us what we need, with optional explicit type specification being just : Type away.

However, so long as C2 doesn't have variable type inference (or any inference for that matter) I think that not having a var keyword is a much better idea. I remember from the days of yore, when I still used AS3, that declarations like this felt pretty cluttered (taken from graphicscorelib):

Code: [Select]
        internal var _spriteSheet : GPUSpriteSheet;
        internal var _vertexData : Vector.<Number>;
        internal var _indexData : Vector.<uint>;
        internal var _uvData : Vector.<Number>;
        protected var _context3D : Context3D;
        protected var _parent : GPUSpriteRenderStage;
        protected var _children : Vector.<GPUSprite>;
        protected var _indexBuffer : IndexBuffer3D;
        protected var _vertexBuffer : VertexBuffer3D;
        protected var _uvBuffer : VertexBuffer3D;
        protected var _shaderProgram : Program3D;
        protected var _updateVBOs : Boolean;

If we were able to see type earlier, I feel like it would have been cleaner.

7
Ideas / Re: [Email suggestion No. 3] type casts in C2 + bugs
« on: November 09, 2018, 10:56:47 PM »
Back when I first started debating this, I was young and inexperienced.
Now, after two years of Rust, I can say that I agree with @lerno that value as Type might be the best solution. It is clear, readable and not as out of place as cast<Type>(val) is.

Moreover, if C2 was ever to introduce any form of generics, cast<Type>(val) would be as deceiving in appearance as sizeof(val) is for newcomers (they both look like functions).

8
Ideas / Re: Struct Function declaration
« on: May 09, 2017, 07:40:09 PM »
how about something like this?
Code: [Select]
func[Point]  void add(self, int32 x) { .. } // add the type to the func keyword, replace replace the instance with self
structfunc void add(Point* p, int32 x) { .. } // just say it's a struct func

The last option was also nice

EDIT:
suggestion No.3:
Code: [Select]
func void add(self*, int32 x) for Point { .. } // variation 1
func void add(Point* self, int32 x) for Point { .. } // variation 2

9
Ideas / Re: [Email suggestion No. 1] macros in C2
« on: July 23, 2016, 02:31:53 PM »
In your previous example about the factorial, there is no reason at all to use a macro,
since the compiler can figure out perfectly well if the function is pure (ie only depends on
the arguments and doesn't access globals). So the whole factorial(x) can be calculated at
compile time if a constant is used as argument.

Yes, it was just an example, not much of a realistic use of a macro. Calculating it a at compile time would be pretty neat.

For unit testing, I almost never use boolean expressions in macros, so instead of (for example)
Code: [Select]
assert_equal(a == b, "a is not b");

it's much better to use
Code: [Select]
assert_equals(a, b);
assert_greater(a ,b);
because the code can then immediately print something like: expected <x>, got <y>.

There might be other cases where a boolean expression is really needed, but I can't think
of them right now.. I'll spent some time thinking about this.

Yes, one of such uses can be when one wants to provide more readable/descriptive errors for failed asserts or if one is testing with a boolean function.

When thinking about the implementation, let's talk about the macro changing variables in the caller's environment,
eg: (the example is a bit contrived, but i hope the meaning is clear)
Code: [Select]
public macro increment_b_with(x) {
   b += x;
}
(In this case, b could also have been added as argument, but for the example it's not).
So when parsing the code, the macro is ok, but when it's used, there must be a variable
b in scope. If not, you ideally want a nice syntax error, like:

caller.c2:10 macro 'mod.increment_b_with' needs external identifier 'b'


A syntax error would be very nice. How about restricting this to only allow changing variables that are in global scope? Changing local variables that were not passed as an argument to the macro could create a lot of mess.

One last idea is to let a developer impose some type restrictions. So for example an argument
must be type struct X. This does however come into the domain of regular functions..

I like this idea, because it brings order to the mess that is C macros. I think it would be an amazing addition which could certainly grasp peoples' attention, just like incremental arrays do. Just this does not delve that deep into regular functions, but it does bring some sane vibe of them.

10
Ideas / Re: [Email suggestion No. 1] macros in C2
« on: July 22, 2016, 11:14:08 AM »
Maybe we can also create a new point that forbids the use of macro's within a macro?

Yes, recursive macros and so on are the bane of C/C++ code and to prevent it is a good idea.

As a technical suggestion, I suggest that macros will expand to AST rather than source code, to prevent the need of preprocessors as it is seen in C/C++.

So to sum up the rules and looks:

design rules:
  • Each macro has to start with the "macro" keyword, followed by the macro's identifier and the contents of the macro
  • The content may be either single value/statement or a multiple lines of statements in {} brackets.
  • Macros support multi-line content by default, no need to use \ to extend number of lines
  • Macros must contain parse-able C2 code
  • When used, an exclamation mark ! must be added to the name of the macro.
  • A macro can be public or not, just like other declarations.
  • There needs to be a distinction
     (also described in the nim link): There are *expression* macros and
     *statement/decl* macros. You cannot have a declaration if a place where
     an expression is expected. It might be possible to discover this, but
     it might be needed for a developer to specify this as well..
  • The argument of a macro must only be an identifier or a literal, expressions are not allowed.
  • No macro can be used within other macros

For point 7, I think that it could be figured out from the insides of the macro beforehand and each macro would be internally pre-assigned a type whether it's a "function" macro or an "expression" macro. Expression macros would be only able to contain an expression, otherwise it could be handled as a statement/function macro

syntax:
Declaration:
Code: [Select]

//statement  macros
macro loudmultiplication(x, y) printf("value %d at line %d in file %s\n", (x*y),  __LINE__, __FILE__);
public macro loudaddition(x, y) printf("value %d at line %d in file %s\n", (x+y), __LINE__, __FILE__);

public macro printfactorial(limit) {
     int64 factorial = 1;
     if(limit > 19) printf("error: the number is too big for signed 64-bit integers");
     else {
          for(int8 i = 0; i <= limit; i++) {
               factorial *= i;
          }
          printf("factorial: %d", factorial);
     }
}

macro myassert(desc, test) {
    tests_ran++;
    if (!(test)) {
        char* error;
        asprintf(&error, "[%s:%d]\x1b[31mTEST FAILED\x1b[0m: %s\n",__FILE__, __LINE__, desc);
        asprintf(&finalmessage, "%s%s", finalmessage, error);
    }
    else {
        char* success;
        tests_passed++;
        asprintf(&success, "[%s:%d]\x1b[32mTEST PASSED\x1b[0m: %s\n", __FILE__, __LINE__, desc);
        asprintf(&finalmessage, "%s%s", finalmessage, success);
    }
}

//expression or literal macros
macro dummyname "dummy";
macro makearray(count) malloc(sizeof(int32) * count);

macro anytrue(x, y, z, a, b, c) {
    (  x || y
    || z || a
    || b || c )
}

//usage
public func void testmacros() {
    loudmultiplication!(25, 14);
    loudaddition!(15, 41);
    printfactorial!(14);
    myassert!("test whether true is true", true);
    puts(dummyname);
    int32[] = makearray(5);
}

On a second thought, how about allowing boolean expressions, too? It is better for unit testing and assertions.

11
Ideas / Re: [Email suggestion No. 3] type casts in C2 + bugs
« on: July 21, 2016, 02:34:16 PM »
I couldn't agree more. The <> syntax just looks like C++ templates is is just plain ugly..

However ugly, it does have the advantage of requiring parentheses around the thing being
cast. With the c-style cast, it's not always obvious what exactly is cast. This has to do with
operator precendence (and could be a source of bugs).

C-style cast are currently not working on purpose. Casts need to be fixed first.


The 2nd 'bug' is also done on purpose for now, since we don't have to check circular initializations now ;)
So the declaration is only added to the scope after it's been done, so after the initialization. But for better
error messages, it might be needed to change this

Yes, I understand it, what I mean is that the compiler is ignoring them, rather than issuing a proper warning about C-style casts or throwing an error.

12
Ideas / Re: [Email suggestion No. 1] macros in C2
« on: July 21, 2016, 02:32:57 PM »
It's a bit strange that some language cling to macros, while others
(C#, Java, etc) never seem to need them. To make a really good macro
system, I tried to write do the *purpose* of macros. What I came up
with:
  • replacing common code
  • inlining (instead of function). This one is actually not valid,
      since a function call is superior if the compiler can inline it.
  • feature selection
the difference with a function is that a macro is able to 'access'
the 'calling' scope.

The Nim language is a bit in the same domain as C2. It has some pretty
nice ideas as well. For macros they stated (something like): "with macros
you can change the AST". Indeed the case if you think about it.

http://nim-lang.org/docs/tut2.html#macros

I agree with your design (1-5). My additions:
6. A macro can be public or not, just like other declarations.
7. There needs to be a distinction
 (also described in the nim link): There are *expression* macros and
 *statement/decl* macros. You cannot have a declaration if a place wher
 an expression is expected. It might be possible to discover this, but
 it might be needed for a developer to specify this as well..
8. The argument of a macro must be an identifier (only). This avoids
    nasty issues like in C:
Code: [Select]
        #define MAX(x, y) (x > y ? x : y)
        int c = MAX(a++, b++)
as this  expands to
Code: [Select]
int c = ((a++) > (b++) ? (a++) : (b++));


I agree with everything here. I propose a small addition to rule 8 and that is to allow literals, too. So

Code: [Select]
mymacro!(5, 10); //fine
mymacro!(x, y); //fine
mymacro!(x++, x*y) //not fine


13
see also this post (http://www.c2lang.org/forum/index.php?topic=56.msg154#msg154).

The library system is currently undergoing an overhaul. In the current system, there would be an interface
file, for example stdio.c2i (in c2libs/libc/). In the libc manifest file there would be an entry also naming
(for C libs) an header file name. During compilation, the header file name would be generated in C-code.
Then during the compilation of the generated C-code, this (system) header (stdio.h) would actually be
used.

In the new system, headers are generated from the c2 interface file. And this generated header would be
used (so #include "stdio.h" (notice the double quotes "" instead of <>). This has the advantage that the
header is guaranteed to be the same as the interface file.


I like this idea very much, amazing addition!

14
   C and C++ are known for requiring a lot of work when one wants their code to be compatible with more OSes, generally to support Linux, Mac OSX and Windows. That usually translates to a lot of macros, especially many #ifdef _WIN32 ones.
   C2 is the evolution of C which aims to evolve all "the" bad or aged aspects of C. My suggestion is to create a library, which I could gladly do, called something in lines of libc2 or libc2core (since libc2 already exists, frankly), which would abstract the portability problems between POSIX-ish systems and systems like Windows, which are only partially POSIX-compliant (and aren't especially at places where it hurts the most) and throw in a few more functions/types/symbols to refresh the old libc, which is also aged.
   A great example is zed_net https://github.com/luciusmagn/zed_net by ZedZull, which handles the great incompatibility problems between using sockets in POSIX and Windows. The link is to my fork of zed_net, since the author frankly deleted the original repo for reasons unknown. In other words, the library itself could be like a libc extension and compatibility layer specifically made for C2. I would like to create it, if you like the idea, since I like making portable software.

15
Ideas / [Email suggestion No. 3] type casts in C2 + bugs
« on: July 19, 2016, 10:26:37 AM »
The current cast<type>(what); does not really fit into C2 syntax wise, since it implies generics and that is not something that fits in C2 as it is now. Bas proposed this syntax in an email a few months ago:

Code: [Select]
(->type)what
This could be much better and due to the arrow, more understandable to those who don't know how casts work beforehand.

casting bug 1: C2C parser completely ignores invalid C-style casts and interprets statements that use it as ones using implicit conversion

example:

Code: [Select]
int32 i = 10;
char c = (char)i;

I think that this syntax should result in an error or at-least warning about C-style casts. Frankly, I know that C-style casts are hard to parse, so I am not sure how easy or hard that is to implement

casting bug 2: C2C does not work properly when I do intentionally a bad thing like this:

Code: [Select]
int32 i = 10;
char d = cast<char>(d); //undeclared identifier error

I think that the proper behavior should be issuing a message/error/warning about using uninitialized variable or casting to itself.

Pages: [1] 2