Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Idle: Wished-for programming language design?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
37 replies to this topic

#1 BGB   Crossbones+   -  Reputation: 1554

Posted 08 June 2013 - 01:44 PM

so, the idea here is basically, thoughts for what a person might want in an "ideal" programming language.

granted, some limits may be set, as what is ideal for one person may not be ideal for another.

 

so, for example, a few general thoughts:

mostly a "fairly generic" syntax, like say a mixture of C, C++, Java, and C# syntax;

can be either compiled to native, or compiled to bytecode and run in a VM;

should have easy access to existing C (and ideally also C++) libraries;

should have some built in mechanisms for internal security and sandboxing (pieces of code within the program can be run with reduced rights, ...);

should have the ability to load bytecode and source programs at run-time, accept dynamically created bytecode, and support an "eval" mechanism;

probably includes optional variant and auto-typing as well (variant-typing being dynamically-typed with optional type-inference, and auto-typing mandating that only a single type be used);

stuff should be portable between OS's and CPU architectures;

...

 

more specific thoughts:

may use a Java-like class declaration syntax (and probably Single Inheritence + Interfaces);

may use a C#-like package/namespace system, and allow more free-form contents declared in source files;

uses a C#-like parsing strategy (mostly avoids the issues of ordering and context dependence from C and C++, and doesn't depend on a few of the "tricks" used in parsing Java, *1);

probably includes a few other features like in C#: pointers, references, structs, properties, operator overloading, ... (*2)

interfaces likely support default methods and fields (*2);

probably uses more of a "nearly everything is an expression" syntax design (*3);

...

 

 

*1: C# basically defines the syntax in terms of more rigid rules which don't depend on declaration context (like C or C++) or on external context (Java).

 

*2: pointers can be made "safer" by supporting implicit bounds-checking, and possibly by placing some limits on allowed pointer type conversions. in most cases, this can be made fairly invisible to code using the pointers.

other features would likely be similar to their analogues in C#, though a property syntax more like AS3's could be considered (slightly less funky than the C# property syntax).

 

*3: a default method allows a method implementation to be provided in an interface, and a default field would allow field declarations within an interface. in effect this makes an interface more analogous to an "abstract base class".

 

*4: basically, like C, but possibly taken a little further. many statements are syntactically actually expressions, just put on their own lines. could possibly also consider adding the concept of tail-calls.

 

 

probably the "landscape" it would live in would build directly on top of the C landscape, with what exists as the "class library" existing to some extent as wrapper libraries. most C API wrapping can be done fairly automatically by tools, allowing C headers/libraries to be made available in a form resembling packages (or namespaces).

 

in my own language "BGBScript" I had called this concept "native packages" and "native import", where the idea was to allow packages to exist which directly represented parts of the C landscape, and could be used for importing/exporting to/from C land. most of the import/export work can be handled fairly automatically by batch-tools (basically, say, you make OpenGL available by, say, invoking a tool and telling it to use "opengl32.dll" and "GL/gl.h" and also give a few other settings, and it spits out any wrapper code and metadata). (a drawback is as-is, separate tools are used for importing/exporting, whereas ideally a single code could handle both at once).

 

there is a possible choice between "package ... { import ...; ...}" and "namespace ... { using ...; ...}", but this is more primarily a syntactic issue (both would be functionally equivalent).

 

 

thoughts?...

 



Sponsor:

#2 ranakor   Members   -  Reputation: 439

Posted 08 June 2013 - 01:52 PM

My ideal language:

A new verion  of C# / .net

Without nulls

Everything is a reference type (can be toggled off on the compiler/ using some form of blocks/ Explicitely declaring some types as NonReference and having an error when passing them where a ref is expected etc) so that there's no 2 basic types for the (very large majority) of applications where speed just doesn't matter at all.

Non backward compatible : remove all legacy features and APIs

MyClass.Members.Test.PropertyName (can be solved by the compiler at compile time, types wouldn't have to have a Members property actually available at runtime, would just be an extention keyword and enable a lot of scenarios which require reflection or AOP to be available built in and at compile time without any safety loss from working with strings)



#3 BGB   Crossbones+   -  Reputation: 1554

Posted 08 June 2013 - 03:21 PM

issue:
nulls, and value types, are actually pretty useful in many cases, and there are still many cases where performance does actually matter...
actually, for practical languages, the concept of null is likely all but inescapable.
 
also, ease of getting things done effectively is also important, and something like lacking nulls and value-types would likely result in a lot of convoluted code trying to work around it (the lack of user-defined value types is already an issue a lot of times when it comes to writing code in Java, and taking away null would likely make all this a bit worse, and probably just result in people poorly recreating it via a Null monad class or similar...).
 
 
to reduce the possibility of null-related exceptions popping up at run-time, a compiler could potentially generate a warning though for cases where a null is likely to pop up and generate a runtime exception, and support a modifier to disallow passing null to certain functions (or assigning it to variables).
 
say, we write something like:

Foo! foo;
...
foo=null;

 
and the compiler is like: "no, you can't do that...".

 

which is basically the logical inverse of:

int? i;
...
i=null;

where normally a compiler would object to assigning null to an integer, but the '?' says it is ok.



#4 Waterlimon   Crossbones+   -  Reputation: 2643

Posted 08 June 2013 - 03:30 PM

Like in c++, there should be a language design idiom stating that you should not pay for what you dont use.

if theres any optional checking, safety or other dynamicisms, they should be optional and preferrably not the go-to method of doing things.

To make the language less horrible due to the lack of ugly dynamic language features, a flexible compile time metalanguageish system should be provided (templates and all, but more flexible, like running any code at compile time if possible. And not duck typed, so there can be code completion...)

o3o


#5 BGB   Crossbones+   -  Reputation: 1554

Posted 08 June 2013 - 04:51 PM

Like in c++, there should be a language design idiom stating that you should not pay for what you dont use.

if theres any optional checking, safety or other dynamicisms, they should be optional and preferrably not the go-to method of doing things.

To make the language less horrible due to the lack of ugly dynamic language features, a flexible compile time metalanguageish system should be provided (templates and all, but more flexible, like running any code at compile time if possible. And not duck typed, so there can be code completion...)

 

generally agreed.

 

in language design, it is often a tradeoff between not providing a check at all, or making the check be implied and generally having the compiler optimize it away when possible.

 

having dynamic features as opt-in makes sense (this is partly how I had already been approaching things in my language, gradually moving away from using dynamic features as the default mechanisms).

 

safety related features are a little bit of a harder issue though, mostly because they may also have implications for code-security, and if there is a possibility that the code may be "untrusted", it generally makes sense for the checks to be enabled by default (and left more as an "opt-out" feature more like that of the C# "unsafe" keyword, where untrusted code using 'unsafe' may result in it being automatically rejected).

 

 

typically, a sort of limited form of generalization + specialization can be provided by variant and auto types.

typically, an auto type will only specialize the types once, requiring the types to be statically provable (basically, like the "auto" type in C++);

 

"variant" is a little less aggressive, and will more often work via one of several mechanisms:

will leave the check as a dynamic type checks (a generic/slow route), for cases where the type can't be statically determined;

will make specialized versions of the code specialized for each type it is used with.

 

a downside though is that handling the dynamic cases for variant does imply some runtime dependence, whereas auto can be handled without depending on the runtime (since if full compile-time specialization can't be done, the compiler will generate an error).

 

there is some implementation-level overlap with concepts like generics and/or templates.

 

 

the general problem with metalanguages which execute code at compile time is that there aren't really many good ways to do this which don't in-turn turn into an awful mess (this was my past experiences trying to bolt a Common-Lisp style macro-system on a language with a C like syntax). I can imagine the idea of trying to hammer together C++-style templates with CL-style macros, and this thought seems... disturbing...

 

so, I guess the thing would be coming up with a good idea for what such a thing should look like.

 

some ideas which I have ran across before have been for "static if()" and "static for()" statements, which basically tell the compiler "this statement will be handled at compile-time", with the the latter basically telling the compiler to unroll the loop in advance. granted, technically "const" or "final" would probably be a better choice here (would have less conflict with various ways in which 'static' is commonly overloaded).

 

one possibility for compile-time execution:

final int x=10;
...
final if(x>5)
{
    //loop executes at runtime
    for(int i=0; i<x; i++)
        { ... }
}
else
{
    //loop is unrolled at compile time
    final for(int i=0; i<x; i++)
        { ... }
}

final virtual int i=x;  //compile time variable (may need better keywords)
final while(i>0)
    { ... }
//expand while-loop branches at compile time, treating 'i' at each step as if it were a compile-time constant.
//likely
...

final {
    //code is executed at compile time (by default)
    ...
    dynamic {
        //code to be executed at runtime
        ...
    }
}

 

or such...



#6 ranakor   Members   -  Reputation: 439

Posted 08 June 2013 - 06:16 PM

issue:
nulls, and value types, are actually pretty useful in many cases, and there are still many cases where performance does actually matter...
actually, for practical languages, the concept of null is likely all but inescapable.
 
also, ease of getting things done effectively is also important, and something like lacking nulls and value-types would likely result in a lot of convoluted code trying to work around it (the lack of user-defined value types is already an issue a lot of times when it comes to writing code in Java, and taking away null would likely make all this a bit worse, and probably just result in people poorly recreating it via a Null monad class or similar...).
 
 
to reduce the possibility of null-related exceptions popping up at run-time, a compiler could potentially generate a warning though for cases where a null is likely to pop up and generate a runtime exception, and support a modifier to disallow passing null to certain functions (or assigning it to variables).
 
say, we write something like:

Foo! foo;
...
foo=null;

 
and the compiler is like: "no, you can't do that...".

 

which is basically the logical inverse of:

int? i;
...
i=null;

where normally a compiler would object to assigning null to an integer, but the '?' says it is ok.

I'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

 

I also mentioned enabling value types when needed, but most programs don't need it really. Most programs aren't games and have pretty much no arithmetic, actually most programs barely use value types at all except where the fact it's a value type doesn't change the semantics (used locally in a block). I don't think the concept of value types serves a useful purpose for everyday's programming, hell there's nothing inherently faster about them, don't forget that value types != on the stack, it's just an implementation choice on the compiler's side not a guarantee, the only actual diference is in use semantics, and that's not a good thing IMHO, a good tradeof would be to

- Have them be reference types (this is a semantic change)

- Add a layer of metata on functions indicating for each parameter if the parameter gets assigned in the function or a nested function

- If not pass it on the stack, still making it act as a reference type but hiding the fact it doesn't internally when it wouldn't change the outcome, no 2 mechanics, no 2 styles to learn, no errors due to passing a parameter and expecting it to / not to change etc.



#7 Ryan_001   Prime Members   -  Reputation: 1479

Posted 08 June 2013 - 07:12 PM

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

Edited by Ryan_001, 08 June 2013 - 07:13 PM.


#8 BGB   Crossbones+   -  Reputation: 1554

Posted 08 June 2013 - 07:59 PM

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

 

or, even, say, implement a linked list with a finite length?... you need something to terminate the list with, and this is generally done with a null...

 

also, a null type is pretty useful when implementing something like a hash-table, where not all the entries will necessarily have valid values.

 

much better I think would be having an explicit "not null" notation, rather than eliminating null from a language...

 

 

now, as for people thinking things were a mistake:

there is also a tired argument that many people also believe that the concept of variable assignment is a mistake.

doesn't really mean that there is as much practical usefulness for languages which lack the concept of variable assignment though (they typically only really gain niche usage).

 

 

sometimes the benefits of a feature outweigh the costs...


Edited by cr88192, 08 June 2013 - 08:19 PM.


#9 ranakor   Members   -  Reputation: 439

Posted 09 June 2013 - 05:47 AM

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

Pointers have nothing to do with this, on the C# side pointers are one thing (used in unsafe blocks) and reference and values a whole other topic, so this is quite out of scope and unrelated to what i was saying.



#10 ranakor   Members   -  Reputation: 439

Posted 09 June 2013 - 05:57 AM

 

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

 

or, even, say, implement a linked list with a finite length?... you need something to terminate the list with, and this is generally done with a null...

 

also, a null type is pretty useful when implementing something like a hash-table, where not all the entries will necessarily have valid values.

 

much better I think would be having an explicit "not null" notation, rather than eliminating null from a language...

 

 

now, as for people thinking things were a mistake:

there is also a tired argument that many people also believe that the concept of variable assignment is a mistake.

doesn't really mean that there is as much practical usefulness for languages which lack the concept of variable assignment though (they typically only really gain niche usage).

 

 

sometimes the benefits of a feature outweigh the costs...

Some things like linked lists would need to change a bit yes, i don't see a problem with that, i'd gladly embrace some change in exchange for getting rid of null. Also all languages don't need to be good for everything, as i mentioned those changes wouldn't necesarily be good for games / realtime apps, but for exemple in years working on business application development, i haven't needed a linked list once, not once.

 

If an entry doesn't have a hash value, then it shouldn't be in a hash table to begin with imho, so that's a positive vote for no nulls from my side, disallowing the kind of hacky "lets fix issue X by using null and changing the expected behavior" type of mentality that resides around it. If something can't properly be defined in a specialized collection, don't try to stuff it in that collection, and be glad the framework is telling you you can't!

 

And yes many people think that "X" or "Y" or "Z", what's noteworthy here is not that "someone" thinks that null shouldn't exist, nor even that someone significant thinks so, it's that the GUY WHO INVENTED IT thinks so, that's quite a huge diference in my book and definately noteworthy.

 

Sure you can find dozens of things you can't do if you remove nulls, but you must first think of 2 things : 1) are those things actually good? and 2) if i try to solve it without nulls, do i not end up with a better result?

 

May not be a good solution as i just think of it as i type but for example linkedlist could simply return element interfaces wraping the value with IElement having current / hasnext/hasprevious and being castable in IPreviousElement:Element if it hasprevious and vice versa, that way you could end up on an ielement that hasnext = false and you'd know it's not castable to an INextElementContainer , if you checked it you'd see it's underlying type is a FinalElement:IElement and that it doesn't contain any null properties. There, double linked list without null.



#11 BGB   Crossbones+   -  Reputation: 1554

Posted 09 June 2013 - 09:33 AM

 

 

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

 

or, even, say, implement a linked list with a finite length?... you need something to terminate the list with, and this is generally done with a null...

 

also, a null type is pretty useful when implementing something like a hash-table, where not all the entries will necessarily have valid values.

 

much better I think would be having an explicit "not null" notation, rather than eliminating null from a language...

 

 

now, as for people thinking things were a mistake:

there is also a tired argument that many people also believe that the concept of variable assignment is a mistake.

doesn't really mean that there is as much practical usefulness for languages which lack the concept of variable assignment though (they typically only really gain niche usage).

 

 

sometimes the benefits of a feature outweigh the costs...

Some things like linked lists would need to change a bit yes, i don't see a problem with that, i'd gladly embrace some change in exchange for getting rid of null. Also all languages don't need to be good for everything, as i mentioned those changes wouldn't necesarily be good for games / realtime apps, but for exemple in years working on business application development, i haven't needed a linked list once, not once.

 

If an entry doesn't have a hash value, then it shouldn't be in a hash table to begin with imho, so that's a positive vote for no nulls from my side, disallowing the kind of hacky "lets fix issue X by using null and changing the expected behavior" type of mentality that resides around it. If something can't properly be defined in a specialized collection, don't try to stuff it in that collection, and be glad the framework is telling you you can't!

 

And yes many people think that "X" or "Y" or "Z", what's noteworthy here is not that "someone" thinks that null shouldn't exist, nor even that someone significant thinks so, it's that the GUY WHO INVENTED IT thinks so, that's quite a huge diference in my book and definately noteworthy.

 

Sure you can find dozens of things you can't do if you remove nulls, but you must first think of 2 things : 1) are those things actually good? and 2) if i try to solve it without nulls, do i not end up with a better result?

 

May not be a good solution as i just think of it as i type but for example linkedlist could simply return element interfaces wraping the value with IElement having current / hasnext/hasprevious and being castable in IPreviousElement:Element if it hasprevious and vice versa, that way you could end up on an ielement that hasnext = false and you'd know it's not castable to an INextElementContainer , if you checked it you'd see it's underlying type is a FinalElement:IElement and that it doesn't contain any null properties. There, double linked list without null.

 

 

but, why not just flag which variables you don't want to ever be null? then it can be largely enforced at compile-time, and all is good.

 

this way, where needed, this can be enforced, and the language can still be useful for doing general purpose programming.

 

also, it wouldn't require common data structures to be implemented with wacky "under the hood" logic either (or lead to people circumventing it using convoluted mechanisms).

 

 

EDIT: sort of like, "Foo! obj=new Foo();" or "@NonNull Foo obj=new Foo();"...

ADD: my language already defines "type!" as an explicit non-null indicator, and exists as the logical inverse of "type?".


Edited by cr88192, 09 June 2013 - 09:46 AM.


#12 Endurion   Crossbones+   -  Reputation: 3693

Posted 09 June 2013 - 11:27 AM

Hmm, regarding the null discussion, having both types, nullable and non nullable would be a good start (c# at least allows nullable for primitive types). Having non nullable as default and nullable as special version would be neat.


Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#13 Memories are Better   Prime Members   -  Reputation: 769

Posted 09 June 2013 - 12:44 PM

C# with the following features would be nice.

- enum as a generic constraint

- ability to use ref / out on properties

- SIMD

 

I am happy with everything else atm in both C# / C++ but then I get told I am too easy to please -.-

 

Oh and people should be fined or jailed for confusing ASP.NET WebForms with ASP.NET MVC



#14 Eidetic Ex   Members   -  Reputation: 133

Posted 09 June 2013 - 12:57 PM

Optional markup used for function argument validation and range restriction, shown in the IDE's "intellisense" tooltips as well.

"void fun(validate(arg < 100) int arg)" would cause an error if arg is greater-than-or-equal to 100.

"void fun(range(5, 10) int arg)" would automatically clamp "arg" in the 5-10 range before the function body executes.

 

Given just how much of programming is mathematics, these always seemed like a no-brainer to me but I've yet to use a language which implements something like them.

 

Fixed point decimals as a primitive type instead of having to rely on 3rd party APIs or rolling your own. They solve so many audio and video problems that I don't understand why we keep trudging on with the pitfalls of floating point numbers in languages that are typically used for game development.



#15 BGB   Crossbones+   -  Reputation: 1554

Posted 09 June 2013 - 01:32 PM

Hmm, regarding the null discussion, having both types, nullable and non nullable would be a good start (c# at least allows nullable for primitive types). Having non nullable as default and nullable as special version would be neat.

 

yeah. conservative here is having non-null as the default behavior for value types, since typically null doesn't make sense for value types.

now, making non-null the default for reference types with explicit nullable references could be interesting, but would still be a bit unorthodox.

 

 

C# with the following features would be nice.

- enum as a generic constraint

- ability to use ref / out on properties

- SIMD

 

I am happy with everything else atm in both C# / C++ but then I get told I am too easy to please -.-

 

Oh and people should be fined or jailed for confusing ASP.NET WebForms with ASP.NET MVC

 

yep.

 

the issue with properties I think is mostly because ref/out are internally implemented as pointers, and supporting them with pointers would lead either to an implementation / performance issue, or to funky semantics (such as the setter for the property not being called until after the function-call returns, rather than immediately whenever the variable is assigned).

 

 

SIMD would also be nice.

a minor issue though is that there isn't really a "standard" cross-architecture SIMD, which would likely mean that the underlying mechanics would need to be abstracted some (potentially at some efficiency cost). this is likely to manifest itself in the HLL either as vector operators, as array-based operators, or some combination thereof.

 

even as such, it would probably still be better regarding usability than the use of ASM or explicit SIMD intrinsics, and higher performance than the use of straight scalar code (say because of programmers being like "screw it, not going to mess with the SSE intrinsics...").



#16 BGB   Crossbones+   -  Reputation: 1554

Posted 09 June 2013 - 02:16 PM

Optional markup used for function argument validation and range restriction, shown in the IDE's "intellisense" tooltips as well.

"void fun(validate(arg < 100) int arg)" would cause an error if arg is greater-than-or-equal to 100.

"void fun(range(5, 10) int arg)" would automatically clamp "arg" in the 5-10 range before the function body executes.

 

Given just how much of programming is mathematics, these always seemed like a no-brainer to me but I've yet to use a language which implements something like them.

 

 

part of the issue here is mostly that range checks don't come free, and typically people only really add them in cases where it is essentially all but necessary in order to ensure correct operation of the underlying VM/runtime (such as the case of bounds-checks on arrays). correct operation of the program is more often seen as an issue for the programmer to deal with.

 

the sibling of this: range-defined numeric types, have existed in a few languages (even as far back as COBOL, and also in languages like Ada), but haven't really caught on due to it being relatively easier to simply have the programmer define things in terms of one of the machine-defined fixed-width numeric types (and presumably, because much of the time programmers don't care much about the exact range of a value much beyond "will it fit?").

 

 

Fixed point decimals as a primitive type instead of having to rely on 3rd party APIs or rolling your own. They solve so many audio and video problems that I don't understand why we keep trudging on with the pitfalls of floating point numbers in languages that are typically used for game development.

 

dunno...

 

 

most compiler people seem to think of fixed point mostly as "an embedded system thing", which leads to such annoyances as there being an ISO standard for fixed-point arithmetic in C, but compilers seemingly only have this enabled when compiling for targets like ARM.

 

it is like having "__int128" that only works on 64-bit targets, why?... it isn't actually really any more complicated to implement "__int128" on 32-bit x86 than it is to implement 64-bit "long-long", except that the performance is a little worse. it does more harm to have types which only exists on certain targets, than it does to have types which may just have lackluster performance on a given target.

 

I have read some compiler maintainers write things which implies that they believe that the DCT transform in a typical image or video codec *actually uses the cos() function*, and was like "sigh..." (a naive DCT using the "cos()" function is far too slow to even really be worthwhile for offline/batch image processing, much less for video...). (not that I don't appreciate having moderately fast sin/cos/sqrt/... functions though).

 

 

luckily at least, it isn't too critical, since fixed-point can be done easily enough using good old integers and shifts...

 

I guess this goes roughly in the same area as explicit endianess modifiers and language support for 16-bit half-floats.



#17 ranakor   Members   -  Reputation: 439

Posted 09 June 2013 - 02:41 PM

 

 

 

'll have to disagree on the null topic, hell even the guy who created the concept of null disagrees and cites it as his worse mistake ever. If you think of it null is a very bad idea, it's a way to represent an incorrect state, so that you can check for that incorrect state later on, what's better is not allowing an incorrect state at any time and sticking to that, this means redisigning many APIs but then that's also why i wouldn't mind breaking changes. I would like a C# without null, without being able to declare something that would lead to null, without the null keyword etc.

I've heard this sentiment echoed a number of places, and being mainly a C++ programmer, any place where I have the luxury I use references, but there are many times where I have to use pointers instead of references.  How do you handle the situation where you require delayed construction of an object?  Or there are circular dependencies? I find I often come across cases where I can't initialize an object to a valid state till a while after the object is created/used.  Some are trivial to work around, but not all.  How do you work around this?  For example, how would you implement a double-linked list?

 

or, even, say, implement a linked list with a finite length?... you need something to terminate the list with, and this is generally done with a null...

 

also, a null type is pretty useful when implementing something like a hash-table, where not all the entries will necessarily have valid values.

 

much better I think would be having an explicit "not null" notation, rather than eliminating null from a language...

 

 

now, as for people thinking things were a mistake:

there is also a tired argument that many people also believe that the concept of variable assignment is a mistake.

doesn't really mean that there is as much practical usefulness for languages which lack the concept of variable assignment though (they typically only really gain niche usage).

 

 

sometimes the benefits of a feature outweigh the costs...

Some things like linked lists would need to change a bit yes, i don't see a problem with that, i'd gladly embrace some change in exchange for getting rid of null. Also all languages don't need to be good for everything, as i mentioned those changes wouldn't necesarily be good for games / realtime apps, but for exemple in years working on business application development, i haven't needed a linked list once, not once.

 

If an entry doesn't have a hash value, then it shouldn't be in a hash table to begin with imho, so that's a positive vote for no nulls from my side, disallowing the kind of hacky "lets fix issue X by using null and changing the expected behavior" type of mentality that resides around it. If something can't properly be defined in a specialized collection, don't try to stuff it in that collection, and be glad the framework is telling you you can't!

 

And yes many people think that "X" or "Y" or "Z", what's noteworthy here is not that "someone" thinks that null shouldn't exist, nor even that someone significant thinks so, it's that the GUY WHO INVENTED IT thinks so, that's quite a huge diference in my book and definately noteworthy.

 

Sure you can find dozens of things you can't do if you remove nulls, but you must first think of 2 things : 1) are those things actually good? and 2) if i try to solve it without nulls, do i not end up with a better result?

 

May not be a good solution as i just think of it as i type but for example linkedlist could simply return element interfaces wraping the value with IElement having current / hasnext/hasprevious and being castable in IPreviousElement:Element if it hasprevious and vice versa, that way you could end up on an ielement that hasnext = false and you'd know it's not castable to an INextElementContainer , if you checked it you'd see it's underlying type is a FinalElement:IElement and that it doesn't contain any null properties. There, double linked list without null.

 

 

but, why not just flag which variables you don't want to ever be null? then it can be largely enforced at compile-time, and all is good.

 

this way, where needed, this can be enforced, and the language can still be useful for doing general purpose programming.

 

also, it wouldn't require common data structures to be implemented with wacky "under the hood" logic either (or lead to people circumventing it using convoluted mechanisms).

 

 

EDIT: sort of like, "Foo! obj=new Foo();" or "@NonNull Foo obj=new Foo();"...

ADD: my language already defines "type!" as an explicit non-null indicator, and exists as the logical inverse of "type?".

Because it doesn't enforce the same thing at all, if you only declare a variable to be non null, then that info cannot propage, if the very concept of null is gone, you can be guaranteed nothing you work with (including framework returned data and data passed to your functions) will ever be null, i don't care about declaring non null variables, i can already do that by never asigning null to them, i care about the concept of null being gone, and i actually LIKE the fact it changes design of the things you mention to work diferently, to me it's less brittle. For example the linked list is as simple to implement without null, insteaf of having linked list elements with current & next, you have Element with current, and FinalElement with Next , inheriting from Element, it's the same thing really, you just removed the use of the null concept for it.



#18 BGB   Crossbones+   -  Reputation: 1554

Posted 09 June 2013 - 03:42 PM

Because it doesn't enforce the same thing at all, if you only declare a variable to be non null, then that info cannot propage, if the very concept of null is gone, you can be guaranteed nothing you work with (including framework returned data and data passed to your functions) will ever be null, i don't care about declaring non null variables, i can already do that by never asigning null to them, i care about the concept of null being gone, and i actually LIKE the fact it changes design of the things you mention to work diferently, to me it's less brittle. For example the linked list is as simple to implement without null, insteaf of having linked list elements with current & next, you have Element with current, and FinalElement with Next , inheriting from Element, it's the same thing really, you just removed the use of the null concept for it.

 

if the variable is declared non-null, then the runtime will not allow null to be assigned to it (this can be enforced both by static inference and, if needed, by throwing an exception when an attempt is made), and if explicit conversions are required, then there is incentive to use it consistently.

 

it is roughly the same sort of thing as keywords like 'const' or 'final'.

 

in the worst case, it is basically in the same camp as goto...


Edited by cr88192, 09 June 2013 - 03:57 PM.


#19 SeraphLance   Members   -  Reputation: 1457

Posted 09 June 2013 - 07:56 PM

Optional markup used for function argument validation and range restriction, shown in the IDE's "intellisense" tooltips as well.

"void fun(validate(arg < 100) int arg)" would cause an error if arg is greater-than-or-equal to 100.

"void fun(range(5, 10) int arg)" would automatically clamp "arg" in the 5-10 range before the function body executes.

 

Given just how much of programming is mathematics, these always seemed like a no-brainer to me but I've yet to use a language which implements something like them.

 

Fixed point decimals as a primitive type instead of having to rely on 3rd party APIs or rolling your own. They solve so many audio and video problems that I don't understand why we keep trudging on with the pitfalls of floating point numbers in languages that are typically used for game development.

 

There's a reason why you don't see this.  This does the same thing:

void fun(int arg)
{
     assert(arg < 100);
}

 

Automatic clamping makes a bit more sense though in some cases, since it presents some potential compile-time optimizations, whereas I don't think the above does.

 

On a related theme, I always wanted to see a "pure" keyword, which tells the compiler (and this can be statically enforced rather easily) that a function has no side effects.  This is nice from both an optimization and a code correctness point of view.



#20 BGB   Crossbones+   -  Reputation: 1554

Posted 09 June 2013 - 09:41 PM

Optional markup used for function argument validation and range restriction, shown in the IDE's "intellisense" tooltips as well.

"void fun(validate(arg < 100) int arg)" would cause an error if arg is greater-than-or-equal to 100.

"void fun(range(5, 10) int arg)" would automatically clamp "arg" in the 5-10 range before the function body executes.

 

Given just how much of programming is mathematics, these always seemed like a no-brainer to me but I've yet to use a language which implements something like them.

 

Fixed point decimals as a primitive type instead of having to rely on 3rd party APIs or rolling your own. They solve so many audio and video problems that I don't understand why we keep trudging on with the pitfalls of floating point numbers in languages that are typically used for game development.

 

There's a reason why you don't see this.  This does the same thing:

void fun(int arg)
{
     assert(arg < 100);
}

 

Automatic clamping makes a bit more sense though in some cases, since it presents some potential compile-time optimizations, whereas I don't think the above does.

 

depends on how assert is implemented, but this sort of thing can be optimized for.

the less certain issue though is how many significant optimizations would be possible with this knowledge.

 

the main case where number ranges comes in relates to optimizing away array bounds checks, but in many other cases the type-systems work in such a way as to limit the usefulness of range-based arithmetic, and to what extent they are useful could be largely served by a few range-check and clamp related intrinsic functions.

 

assert(range(arg, 0, 50));

//or:

assert(arg.range(0, 50));

 

likewise:

y=clamp(x, 0.0, 1.0);

or:

y=x.clamp(0.0, 1.0);

 

 

On a related theme, I always wanted to see a "pure" keyword, which tells the compiler (and this can be statically enforced rather easily) that a function has no side effects.  This is nice from both an optimization and a code correctness point of view.

 

from an optimization POV, this case can also be detected easily enough with or without a keyword.

however, the benefit that such a keyword would have is more that it allows the compiler to enforce this case (like, say, you intended the function to be pure but missed something).






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS