Jump to page: 1 28  
Page
Thread overview
Programming Language for Games, part 3
Nov 01, 2014
bearophile
Nov 01, 2014
Paulo Pinto
Nov 01, 2014
Paulo Pinto
Nov 01, 2014
Paulo Pinto
Nov 01, 2014
bearophile
Nov 01, 2014
Paulo Pinto
Nov 02, 2014
Walter Bright
Nov 02, 2014
Paulo Pinto
Nov 02, 2014
Walter Bright
Nov 02, 2014
Walter Bright
Nov 02, 2014
Walter Bright
Nov 02, 2014
Walter Bright
Nov 02, 2014
Walter Bright
Nov 02, 2014
bearophile
Nov 02, 2014
Walter Bright
Nov 02, 2014
H. S. Teoh
Nov 01, 2014
Walter Bright
Nov 01, 2014
Walter Bright
Nov 01, 2014
bearophile
Nov 01, 2014
Walter Bright
Nov 01, 2014
bearophile
Nov 02, 2014
Walter Bright
Nov 02, 2014
bearophile
Nov 02, 2014
H. S. Teoh
Nov 02, 2014
Walter Bright
Nov 02, 2014
bearophile
Nov 02, 2014
Walter Bright
Nov 02, 2014
bearophile
Nov 02, 2014
Walter Bright
Nov 03, 2014
Nick Treleaven
Nov 04, 2014
Walter Bright
Nov 04, 2014
H. S. Teoh
Nov 04, 2014
Walter Bright
Nov 06, 2014
Nick Treleaven
Nov 06, 2014
Walter Bright
Nov 04, 2014
Johannes Pfau
Nov 06, 2014
Nick Treleaven
Nov 02, 2014
Meta
Nov 02, 2014
bearophile
Nov 03, 2014
Paulo Pinto
Nov 03, 2014
bearophile
Nov 03, 2014
Shriramana Sharma
Nov 02, 2014
H. S. Teoh
Nov 02, 2014
Paolo Invernizzi
Nov 02, 2014
Paolo Invernizzi
Nov 02, 2014
Rikki Cattermole
Nov 03, 2014
John
Nov 03, 2014
MattCoder
Nov 03, 2014
Walter Bright
Nov 02, 2014
ponce
Nov 02, 2014
Ary Borenszweig
Nov 04, 2014
thedeemon
Nov 04, 2014
Jacob Carlborg
Nov 04, 2014
Meta
Nov 04, 2014
deadalnix
Nov 04, 2014
Jacob Carlborg
Nov 04, 2014
deadalnix
Nov 05, 2014
Jacob Carlborg
Nov 05, 2014
deadalnix
Nov 04, 2014
Jacob Carlborg
November 01, 2014
Third part of the "A Programming Language for Games", by Jonathan Blow:
https://www.youtube.com/watch?v=UTqZNujQOlA

Discussions:
http://www.reddit.com/r/programming/comments/2kxi89/jonathan_blow_a_programming_language_for_games/

His language seems to disallow comparisons of different types:

void main() {
    int x = 10;
    assert(x == 10.0); // Refused.
}


I like the part about compile-time tests for printf:
http://youtu.be/UTqZNujQOlA?t=38m6s

The same strategy is used to validate game data statically:
http://youtu.be/UTqZNujQOlA?t=55m12s

A screenshot for the printf case:
http://oi57.tinypic.com/2m5b680.jpg

He writes a function that is called to verify at compile-time the arguments of another function. This does the same I am asking for a "static precondition", but it has some disadvantages and advantages. One advantage is that the testing function doesn't need to be in the same module as the function, unlike static enums. So you can have the function compiled (separated compilation). Perhaps it's time for DIP.

Bye,
bearophile
November 01, 2014
On Saturday, 1 November 2014 at 11:31:32 UTC, bearophile wrote:
> Third part of the "A Programming Language for Games", by Jonathan Blow:
> https://www.youtube.com/watch?v=UTqZNujQOlA


Thanks for the link. I only have time to skim it, but I think the region-based allocation that he was concerned about in the previous talk might be handled with some kind of tuple-magic?

bike := uniqptr_tuple<Frame,Wheel,Wheel>(myallocator)

// =>uniq_ptr to  tupleof(frameinstance,wheelinstance,wheelinstance)
November 01, 2014
Am 01.11.2014 um 12:31 schrieb bearophile:
> Third part of the "A Programming Language for Games", by Jonathan Blow:
> https://www.youtube.com/watch?v=UTqZNujQOlA
>
> Discussions:
> http://www.reddit.com/r/programming/comments/2kxi89/jonathan_blow_a_programming_language_for_games/
>
>
> His language seems to disallow comparisons of different types:
>
> void main() {
>      int x = 10;
>      assert(x == 10.0); // Refused.
> }
>
>
> I like the part about compile-time tests for printf:
> http://youtu.be/UTqZNujQOlA?t=38m6s
>
> The same strategy is used to validate game data statically:
> http://youtu.be/UTqZNujQOlA?t=55m12s
>
> A screenshot for the printf case:
> http://oi57.tinypic.com/2m5b680.jpg
>
> He writes a function that is called to verify at compile-time the
> arguments of another function. This does the same I am asking for a
> "static precondition", but it has some disadvantages and advantages. One
> advantage is that the testing function doesn't need to be in the same
> module as the function, unlike static enums. So you can have the
> function compiled (separated compilation). Perhaps it's time for DIP.
>
> Bye,
> bearophile

Just started watched the beginning, will watch the rest later.

I find interesting that he also bases part of the language in how the ML languages look like.

So it seems that being C like is out for language design, as most modern languages are following ML like grammars.

Another trend, which I find positive, is how many people are now (finally!) assuming that C widespread into the industry was after all not that good, in terms of bugs/line of code.

Now we need another 30 years until D, Rust, Swift, Nim, <place language name here>, get to replace C and C++.


--
Paulo
November 01, 2014
On 11/1/2014 4:31 AM, bearophile wrote:
> His language seems to disallow comparisons of different types:
>
> void main() {
>      int x = 10;
>      assert(x == 10.0); // Refused.
> }

More than that, he disallows mixing different integer types, even if no truncation would occur.


> I like the part about compile-time tests for printf:
> http://youtu.be/UTqZNujQOlA?t=38m6s

Unnecessary with D because writeln checks it all. Even so, if printf were a template function, D can also check these things at compile time.


> The same strategy is used to validate game data statically:
> http://youtu.be/UTqZNujQOlA?t=55m12s

D allows extensive use of compile time validation.


> He writes a function that is called to verify at compile-time the arguments of
> another function. This does the same I am asking for a "static precondition",
> but it has some disadvantages and advantages. One advantage is that the testing
> function doesn't need to be in the same module as the function, unlike static
> enums. So you can have the function compiled (separated compilation). Perhaps
> it's time for DIP.

D can run arbitrary functions at compile time even if they are in different files.

November 01, 2014
On 11/1/2014 4:31 AM, bearophile wrote:
> Third part of the "A Programming Language for Games", by Jonathan Blow:
> https://www.youtube.com/watch?v=UTqZNujQOlA

Jonathan is reinventing D with a somewhat different syntax. Some points on the video:

* The defer statement works pretty much exactly like D's scope guard:

   http://dlang.org/statement.html#ScopeGuardStatement

* "for n: 1..count" is the same as D's "foreach (n; 1..count)"

* dynamic arrays work pretty much the same as D's

* for over an array in D:
    foreach (it; results) ...

* D does the check function thing using compile time function execution to check template arguments.

* D also has full compile time function execution - it's a very heavily used feature. It's mainly used for metaprogramming, introspection, checking of template arguments, etc. Someone has written a ray tracer that runs at compile time in D. D's compile time execution doesn't go as far as running external functions in DLLs.

* D has static assert, which runs the code at compile time, too. The space invaders won't run at compile time, because D's compile time code running doesn't call external functions in DLLs. I actually suspect that could be a problematic feature, because it allows the compiler to execute user supplied code which can do anything to your system - a great vector for supplying malware to an unsuspecting developer. The ascii_map function will work, however.

November 01, 2014
Walter Bright:

> * for over an array in D:
>     foreach (it; results) ...

D is better here, because it doesn't introduce magically named variables.


> * D does the check function thing using compile time function execution to check template arguments.

This is not nearly enough. I have written a lot about this.


> * D also has full compile time function execution - it's a very heavily used feature. It's mainly used for metaprogramming, introspection, checking of template arguments, etc. Someone has written a ray tracer that runs at compile time in D. D's compile time execution doesn't go as far as running external functions in DLLs.

His "compile time execution" is different and probably better: the whole language is available because it uses an intermediate bytecode. This makes it more flexible and avoids the need of having essentially two different implementations of the language.


> The ascii_map function will work, however.

The ASCII map example doesn't work in D because of reasons I have explained a lot in past posts.

Bye,
bearophile
November 01, 2014
On Saturday, 1 November 2014 at 17:17:34 UTC, Paulo Pinto wrote:
> Another trend, which I find positive, is how many people are now (finally!) assuming that C widespread into the industry was after all not that good, in terms of bugs/line of code.
>
> Now we need another 30 years until D, Rust, Swift, Nim, <place language name here>, get to replace C and C++.

Jonathan referenced Mike Action, who when asked about what C++ vs C said he preferred C and that using C++ was cultural:

http://www.youtube.com/watch?v=rX0ItVEVjHc&feature=youtu.be&t=1m23s

He also stated time and time again that the hardware is the platform. I think that aspect is missing a bit from D unfortunately.

But in 30 years hardware will have changed a lot…
November 01, 2014
On 11/1/2014 1:33 PM, bearophile wrote:
> Walter Bright:
> D is better here, because it doesn't introduce magically named variables.

I agree that the implicit variable is not good.


>> * D does the check function thing using compile time function execution to
>> check template arguments.
> This is not nearly enough. I have written a lot about this.

I don't agree. Compile time checking can only be done on compile time arguments (obviously) and template functions can arbitrarily check compile time arguments.

I know you've suggested extensive data flow analysis, but Jonathan's language doesn't do that at all and he neither mentioned nor alluded to the concept of that.


>> * D also has full compile time function execution - it's a very heavily used
>> feature. It's mainly used for metaprogramming, introspection, checking of
>> template arguments, etc. Someone has written a ray tracer that runs at compile
>> time in D. D's compile time execution doesn't go as far as running external
>> functions in DLLs.
>
> His "compile time execution" is different and probably better: the whole
> language is available because it uses an intermediate bytecode. This makes it
> more flexible and avoids the need of having essentially two different
> implementations of the language.

He has two implementations - a bytecode interpreter, and a C code generator.

D's CTFE restrictions are:
1. no global variables
2. no pointer math
3. no external code execution

While this prevents you from running space invaders at compile time, I haven't seen much of any practical limitation for things that CTFE is used for.


>> The ascii_map function will work, however.
> The ASCII map example doesn't work in D because of reasons I have explained a
> lot in past posts.

Like what?

November 01, 2014
Am 01.11.2014 um 22:20 schrieb "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= <ola.fosheim.grostad+dlang@gmail.com>":
> On Saturday, 1 November 2014 at 17:17:34 UTC, Paulo Pinto wrote:
>> Another trend, which I find positive, is how many people are now
>> (finally!) assuming that C widespread into the industry was after all
>> not that good, in terms of bugs/line of code.
>>
>> Now we need another 30 years until D, Rust, Swift, Nim, <place
>> language name here>, get to replace C and C++.
>
> Jonathan referenced Mike Action, who when asked about what C++ vs C said
> he preferred C and that using C++ was cultural:
>

I mean in terms of unsafe code and the amount of money spent in research and bug fixing that could have been avoided, if C wasn't as it is.

I wouldn't be that vocal about C if:

- arrays were bound checked (just use a compiler flags and dataflow to remove them like any sane language)

- enums were strong typed

- had reference parameters

- had namespaces or real modules

- no implicit type conversions

- had a sane macro system

But I guess D already covers it...


--
Paulo
November 01, 2014
Walter Bright:

> I know you've suggested extensive data flow analysis,

The "static enum" (and related ideas) I've suggested require no flow analysis.


> Compile time checking can only be done on compile time arguments (obviously) and template functions can arbitrarily check compile time arguments.

In D it's easy to define a function that you call at compile-time to test that some compile-time data is well formed, I do this often. This is a simple example:


import std.range, std.algorithm;

alias Nibble = ubyte; // 4 bits used.
alias SBox = immutable Nibble[16][8];

private bool _validateSBox(in SBox data) @safe pure nothrow @nogc {
    return data[].all!((ref row) => row[].all!(ub => ub < 16));
}

struct GOST(s...) if (s.length == 1 && s[0]._validateSBox) {
    private static generate(ubyte k)() @safe pure nothrow {
        return k87.length.iota
               .map!(i=> (s[0][k][i >> 4] << 4) | s[0][k - 1][i & 0xF])
               .array;
    }

    // ...
}

void main() {
    enum SBox cbrf = [
      [ 4, 10,  9,  2, 13,  8,  0, 14,  6, 11,  1, 12,  7, 15,  5,  3],
      [14, 11,  4, 12,  6, 13, 15, 10,  2,  3,  8,  1,  0,  7,  5,  9],
      [ 5,  8,  1, 13, 10,  3,  4,  2, 14, 15, 12,  7,  6,  0,  9, 11],
      [ 7, 13, 10,  1,  0,  8,  9, 15, 14,  4,  6, 12, 11,  2,  5,  3],
      [ 6, 12,  7,  1,  5, 15, 13,  8,  4, 10,  9, 14,  0,  3, 11,  2],
      [ 4, 11, 10,  0,  7,  2,  1, 13,  3,  6,  8,  5,  9, 12, 15, 14],
      [13, 11,  4,  1,  3, 15,  5,  9,  0, 10, 14,  7,  6,  8,  2, 12],
      [ 1, 15, 13,  0,  5,  7, 10,  4,  9,  2,  3, 14,  6, 11,  8, 12]];

    GOST!cbrf g;
    // ...
}


But you can run such compile-time tests only on template arguments, or on regular arguments of functions/constructors that are forced to run at compile-time. But for me this is _not_ enough. You can't implement the printf test example he shows (unless you turn the formatting string into a template argument of printf, this introduces template bloat and forbids you to have run-time format strings, or forces you to use two different syntaxes or to create two different print functions).

I'd like a way to run compile-time tests for the arguments of a regular function/constructor if they are known at compile-time.

So here I'd like a way to perform a compile-time test of the arguments of the call of #1 (and to not perform them for the call #2 because its argument is not a compile-time constant) (note that here both foo calls are not run at compile-time, and this is good):


void main() {
    auto x = foo(1); // #1
    int n = bar();
    auto y = foo(n); // #2
}


Currently if you want to do the same thing in D you have to use something like:

void main() {
    auto x = foo(ctEval!test(1)); // #1b
}


(Where "test" is a function that tests the argument and "ctEval" is a little template that forces to run "test" at compile time (here "foo" itself is not run). This becomes not much practical if you have arrays of values, or lot of data, etc, it's not *transparent* at all for the user, and the user can forget to use ctEval).



So this is useful in a large number of cases. If instead of foo() there's a call to a constructor, we become able to verify "game data" at compile time where possible while avoiding templates, and running the actual functions only at run-time.


Probably there are various ways to solve this problem. A lot of time ago I have suggested a "enum precondition":

int foo(in int x)
enum in(x) {
    // Optional enum pre-condition.
} in {
    // Optional normal pre-condition.
} body {
    // Function body.
}


The idea is that if foo is called with literals or compile-time (enum) arguments (here just the x argument is required to be known at compile-time) then it performs the tests inside the enum precondition at compile-time. If the arguments are run-time values then the enum precondition is ignored (and eventually the normal pre condition runs at run-time. Sometimes the two pre-conditions contain the same code or call the same testing function).

If you want to implement this idea very well, you can keep the enum precondition as source code (like with templates) so you can run it at compile-time when the arguments are known at compile-time.

Bye,
bearophile
« First   ‹ Prev
1 2 3 4 5 6 7 8