Skip to main content
GameDev.net gamedev.net
🔒 Locked

New programming idea

Started by animator Sep 23, 2010 at 4:06 PM 14 replies 2k views
Original Post
animator
animator
Here is my programming idea for a simpler language. Tell me if its been done before. It is more like natural language.

IF x==(3 or 4)

in c++ would be: if(x==3 || x==4)

IF x(==3 or >5)

in c++ would be: if(x==3 || x>5)

IF (x or y)>3

in c++ would be: if(x>3 || y>3)

IF x(>(y and z) or ==7)

in c++ would be: if( (x>y && x>z) || x==7)

IF (height OF (x or y))>20

in c++ would be: if(x.height>20 || y.height>20 )

IF (height or width) OF x >30

in c++ would be: if(x.height>30 OR x.width>30)


Why is this useful? Well consider writing this in c++:

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)


Me in a nutshell - Patchwork Personalities.
snake5
snake5
That language you're thinking about might be more useful for scripts, although I don't believe that somewhere in your code you'd find yourself struggling with..
Quote:
IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)

Besides, C++ is meant to give control over your code -- who knows how would a compiler convert that line? There's simply no perceptible logic in that line. And that's what every programming language designer is trying to avoid. :D
speciesUnknown
speciesUnknown
Quote:
Original post by animator
Here is my programming idea for a simpler language. Tell me if its been done before. It is more like natural language.

IF x==(3 or 4)

in c++ would be: if(x==3 || x==4)

IF x(==3 or >5)

in c++ would be: if(x==3 || x>5)

IF (x or y)>3

in c++ would be: if(x>3 || y>3)

IF x(>(y and z) or ==7)

in c++ would be: if( (x>y && x>z) || x==7)

IF (height OF (x or y))>20

in c++ would be: if(x.height>20 || y.height>20 )

IF (height or width) OF x >30

in c++ would be: if(x.height>30 OR x.width>30)


Why is this useful? Well consider writing this in c++:

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)


Typing is not the bottleneck of programming. The bottleneck of programming is architectural issues; people incapable of understand if (x == 3 || x == 5) wont be capable of understanding how to implement a callback interface, a message pump, or basic security.

Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Washu
Washu
Programming is a lot like a legal document, the words contained have specific meanings with clear definitions to reduce ambiguity.

Your proposed grammar has none of those things.
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Telastyn
Telastyn
Quote:
Original post by animator
Here is my programming idea for a simpler language. Tell me if its been done before. It is more like natural language.


Literate programming is the keywords you probably want to search for. That said, I don't find this syntax too nice. (and there's no way in hell it's 'simpler')

That said, I'm working on a programming language that will allow this sort of nefarious work. Note (for those that are actually a little familiar with Tangent) that this is some of the 3.0 work, and some of the syntax isn't quite solid yet...

Because I'm curious how it would look:

Quote:

IF x==(3 or 4)


(and for the other boolean infix operator with or/and)

public class int{    public static this (int<->int->bool: op) (OptionalCandidates<int>: rhs) => bool{        foreach( int: candidate in rhs){            if( this op candidate ){                return(true);            }        }                return(false)    }}// Implement generic OptionalCandidates and overload //  <tt>int<->int->OptionalCandidates<int>: or</tt> to do the generation.


Then your syntax (or something very similar) would work in the language.

Quote:

IF (height OF (x or y))>20


public infer(any:T) (this T->int: member) of (OptionalCandidates<T>: candidates) => OptionalCandidates<int>{    local OptionalCandidates<int> result = new OptionalCandidates<int>;    foreach( T: candidate in candidates ){        result.Add(candidate.member);    }    return(result);}


Quote:

Why is this useful? Well consider writing this in c++:

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)


Which is generally doing a join on all of those members and possibilities, which is rare and kinda icky. I'm not saying that things perhaps shouldn't be more like natural language, but your syntax isn't really that much more readable. And indeed, this sort of simple declarative problem isn't really something that benefits greatly from the paradigm.

[Edited by - Telastyn on September 23, 2010 5:31:38 PM]
ApochPiQ
ApochPiQ
Quote:
Original post by animator
IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)


If I could figure out what exactly that was supposed to do, I'd demonstrate how easy it is to do in languages with C-like syntax.

But I can't figure it out, so IMHO your experiment has totally failed to improve on readability and ease of understanding.


[edit] OK, maybe that's a bit unfair. I did figure it out after a minute or three of puzzling. I'd do it this way instead in Epoch, provided the appropriate entity extensions:

for(animal in list(critter, cat, dog, pigeon)){   for(property in list(identifier, height, width, length))   {       if(animal.property > 10 && animal.property < 30)          foo()   }}


Now I can specify a dynamic container instead of a hard coded list of animals. Or I can specify a dynamic list of properties instead of hard coding those. I can then run the loop in parallel on multiple threads, or on the GPU if I really feel like it. And so on.



I'll applaud your attempt at improving on things - it's certainly not a bad idea, it just isn't a successful one. Keep that attitude - trying to find simpler, safer, and more convenient ways to write code is a Good Thing™. It just takes a hell of a lot of practice to get good at it [smile]
Antheus
Antheus
Quote:
Original post by animator
Tell me if its been done before.


COBOL and named conditions.

Interestingly enough, today the equivalent would be done using closures.
return0
return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?
ApochPiQ
ApochPiQ
Quote:
Original post by return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?



No. What we're saying is that the improvement is too marginal to justify the overhead in learning yet another syntax. Besides, in cases like the one in the OP (which should be damned rare in real code) a solution similar to the one I posted is generally how things will work anyways.
Antheus
Antheus
Quote:
Original post by return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?


No.

C++ doesn't allow members to be manipulated in such way, so comparing to that isn't possible. Dynamic languages make this much simpler already.

But this particular example is OLAP cube. And this type of operation is much more familiar in rule engines.

It could be implemented in Ruby or any language which does not make strong distinction between types, attributes and values and in addition allows reflection.

In Java there is Drools.

This type of languages have their place, especially since they can be coupled with very strong back-ends to do all kinds of validation. But they are also fairly niche in their applicability. Too many real problems require exceptions and special cases, meaning the clean syntax either doesn't make it possible or requires very verbose workarounds.
apatriarca
apatriarca
Functional languages are also very powerful in this regard because of the way they can work with functions. In haskell you can for example implement this
IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30)

as
if any (\x-> x > 10 && x < 30) [p a | a <- [cat, dog, pidgeon], p <- [height, width, length]]
Matias Goldberg
Matias Goldberg
Quote:
Original post by return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?


Here:
bool between( int value, int min, int max ){ return value < max && value > min;}if( between( cat.width, 10, 30 ) ||     between( cat.height, 10, 30 ) ||    between( cat.length, 10, 30 ) ||    between( dog.width, 10, 30 ) ||     between( dog.height, 10, 30 ) ||    between( dog.length, 10, 30 ) ||    between( pidgeon.width, 10, 30 ) ||     between( pidgeon.height, 10, 30 ) ||    between( pidgeon.length, 10, 30 ) ){}


We can go even further refactoring using polymorphism:
bool between( int value, int min, int max ){ return value < max && value > min;}class Base{  int width;  int height;  int length;};class Cat : public Base {};class Dog : public Base {};class Pidgeon : public Base {};Base base[3];base[0] = cat;base[1] = dog;base[2] = pidgeon;//The actual code you will often be dealing starts herebool isBetween = false;for( int i=0; i<3 && isBetween == false; ++i ){ isBetween |= between( base.width, 10, 30 ) |              between( base.height, 10, 30 ) |              between( cat.length, 10, 30 ) );}if( isBetween ){}


This one may look harder for a newbie, but it's actually very clean since you should keep the class definitions apart in different header files (so you would only be looking at the loop) and it scales much better. Here you have 3 objects, but when you have thousands of them, say bye bye to that syntax you're proposing.
And, this code will remain identical regardless the number of objects to compare.

Also the purpose (one of many) of C is to provide a cross platform with low level access to the system you're working on. It's like assembly language without the disadvantage of becoming obsolete once you change to a different CPU instruction set, and having to learn a new set of instructions.

When you convert 18 boolean comparisons into a single line, you're hiding the fact this is a very expensive operation and needs looking for. Possibly refactoring into something more efficient.
This is one of the "why" your syntax suits more as a scripting language, rather a replacement of C. (the other big reason has also been said, which is strictness in the language and loss of ambiguity)

Cheers
Dark Sylinc

Edit: This variation is also nice:
bool between( int value, int min, int max ){ return value < max && value > min;}template <class T> bool animalBetween( const T &value, int min, int max ){ return between( T.width, min, max ) || between( T.height, min, max ) || between( T.length, min, max );}if( animalBetween( cat, 10, 30 ) ||     animalBetween( dog, 10, 30 ) ||     animalBetween( pidgeon, 10, 30 ) ){}
Telastyn
Telastyn
Quote:
Original post by return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?


To be honest, the second is likely far easier for machines to parse, and far easier to parse unambiguously/as the programmer expects.
Emergent
Emergent
A nice, consistent way to express all of this would be with set union, intersection, and inclusion operators.

e.g.,

if( x in {3, 4} )

if( x in {3} U {z | z > 5} )

...etc. The latter example would be improved even more by the inclusion of something like an Iverson bracket (though that creates indicator functions and we really want sets).

The point is that it seems that by introducing just a little set notation you can do all of what you want in a totally unambiguous way (to address e.g. Washu's complaint).

Other posters (like Antheus) have nice examples of programming languages that have this sort of thing by other names. And in fact, Boost's set libraries probably give you halfway-decent syntax for doing this in plain old C++.
stonemetal
stonemetal
Quote:
Original post by return0
Are you guys really saying that

IF (height or width or length) OF (cat or dog or pidgeon) (>10 AND <30) {}

and

if ( ((cat.height <30 && cat.height >10) || (cat.width <30 && cat.width >10) || (cat.length<30 && cat.length>10)) || ((dog .height <30 && dog .height >10) || (dog .width <30 && dog .width >10) || (dog.length<30 && dog .length>10)) ||((pidgeon.height <30 && pidgeon.height >10) || (pidgeon.width <30 && pidgeon.width >10) ||(pidgeon.length<30 && pidgeon.length>10))) {}

are equally simply to parse?


No I am saying the second is easier to parse because I can go through and say it is CNF,DNF or neither. since it is DNF I can look at each term individually and decide if it should be true or not. The first version gives me no such ability. The second version has a certain locality about it. The values being compared are next to each other. The first version I have to jump all over the place and mentally construct each term.
Zahlman
Zahlman
Quote:
Original post by animator
IF (x or y)>3

in c++ would be: if(x>3 || y>3)


Please consider carefully what happens when x and y are boolean values instead.

Consider (x or y) == false.

How does this behave in C++?

How would it behave under your proposal?

How would you get the C++ behaviour under your proposal?

Can you see how a lot of people would expect the C++ behaviour?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.