What does it take to make a language

Pages: 123
I think if you're going to build a language that is partially based on C++, I'd like to see these features:

1. From C++0x, auto and decltype.
2. Better variadic template support (no cons and cdr stuff)
3. Introspection/reflection
4. Ability to extend enums
5. Ability to output enum type variables using the string mnemonic instead of the number (support both ways)
6. A bitfield type -- which is like an enum, but natively allows logical operators
7. Ability to create new operators, including operator[] that takes more than one parameter
8. Concepts, in a nutshell -- An object presents multiple "interfaces" -- sets of variables/functions. I can inherit entire objects or just interfaces of objects. I can friend only interfaces.

etc etc
I would add:
1. Better variadic functions. (edit: allowing a type-safe extensible version of printf)
2. Make std::string the builtin type of string literals, with casts to int, float etc. doing the right thing.
3. Regexes.
4. Real lambdas.
5. Better support for exceptions (no terminate(), instead prints an error to stderr).
6. operator renew[] (alternately, replace arrays with a builtin version of std::vector)
7. auto and decltype
8. create new operators from undefined symbol strings like -< or +^, or maybe unicode.
9. ability to call the constructor separate from allocation.
10. accessors that look like members (allowing you to change the underlying implementation)
Last edited on
Jsmith:
1. I guess the C++0x auto could be useful and maybe decltype, though couldn't auto be used instead?
2. Variadic templates? How would this work?
3. typeof() and typeid should cover this
4. How should this and class extension be done?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//like this?
class foo{
    type bar;}

enum color{
    black=0,
    red,
    blue};

//Keyword extend extends class/enumeration
extend foo{
    type value;};

extend color{
    green,
    magenta};

//or this?
class foo{
    type bar};

enum color{
    black=0,
    red,
    blue};

//Second "declaration" extends class/enumeration
class foo{
    type value};

enum color{
    green,
    magenta};

Personally, I like the extend keyword because it tells anyone reading the code that there is more to that class/enum

5. Like this?

1
2
3
4
5
6
7
8
enum color{
    red,
    green,
    blue};

int main(){
    color c=blue;
    color c2=enum("blue");}

6. Maybe an enum can be declared like this: enum name:typename{/* */} where the enum is a bunch of arbitrary values of type typename that are in the name namespace
7. Shouldn't the revised va_list cover this? Or should the [] operator be declared like c++'s () operator?
8. That's a really interesting idea... So you would declare an interface and any object that inherits it would inherit the members of every class in the interface?

Rocketboy9000:
1. The revised va_list should cover this
2. I already mentioned doing this
3. I'm not really familiar with regexes - what are they?
4. I'm not sure what this is, either
5. What about a way to call a function if an exception is thrown? That way you can see what happened even if there's no console
6. See jsmith #1
7. Sounds like a good ide
8. I'm not sure what you mean

New idea: non const class member default values
The regex, or regular expression, is a mini-language for matching classes of strings. For example: "b*a+|c" matches any number including zero b's and at least one a, or just a c. so it matches "a", "c", "aaaa", "bba" but not "b" or "abc". They're built in in Perl, Python, and Ruby among others, and are available for C/C++ through "regex.h".
A lambda is a function declared inside an expression. They make it easier to use abstract algorithms.
By 8 I mean like this:
Range operator .. (double,double);
Since 2.5 .. 3.5 has no existing meaning, that operator declaration would be valid.
Whoops, I skipped 6 and 8, so my responses should be:

1. The revised va_list should cover this
2. I already mentioned doing this
3. I'm not really familiar with regexes - what are they?
4. I'm not sure what this is, either
5. What about a way to call a function if an exception is thrown? That way you can see what happened even if there's no console
6. What do you mean?
7. See jsmith #1
8. How would I do that? Didn't the people who made C++ decide against it because it would be too complicated or something?
9. Sounds like a good idea
10. I'm not sure what you mean
About making new operators:

What if I tried to make an operator *-?
What would 2*-2 be?

I like the extend keyword because it tells anyone reading the code that there is more to that


Then you would be stuck including files in a specific order.
Like I said, make it illegal to make an operator if it would be ambiguous.
By accessors that look like members, I mean like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A{
    double b;
    public:
    int a{
        return int(b);
    }
    void a=(int i){
         b-=int(b);
         b+=i;
    }
}
int main(){
    A x;
    x.a = 1;//uses member a=.
    x.a += 2;//implicitly uses member a= and member a.
}

As you can see, a looks like it's an int member, but is in fact an accessor to the int part of the double b.
Last edited on
^How could you tell?
You could always add other operators to make the other ones ambiguous.
Hmm, maybe only allow to use characters that aren't in the other operators.
I'm not sure I like that - the a= operator makes it look like you're assigning a value to a member of x. Maybe operators should always contain only characters from a limited set? Then you could check if a certain defined operator could be ambiguous. The problem with that second step is that there's no way of telling if the programmer is calling the new operator or the operator of the rhs object and then an operator that takes the return type of that operator and the lhs object.

Is f-*p dereferencing a pointer and subtracting it from x, or calling operator-*()?

Granted, that can only be ambiguous with operators that are on the lhs of the rhs object, or the rhs of the lhs object. But, I can easily imagine how difficult it could get to determine what's going on if people could define new operators.
Sorry that was supposed to be the things that look like members but are in fact accessors.
Yes, I admit that defining new operators could get hairy, but operator overloads in general are weird and confusing.
In the statement a=b; references and classes make you wonder what 'a' means. Operator overloading makes you wonder what '=' means.
^That's why they limit you to only overloading the "normal" operators. So you can get the same semantics as a built-in type. And they trust that you won't overload it to do some stupid (like operator -() saving the object to a file or something).
Hmm, yeah I suppose custom operators would only really work in a less complicated language. What do you think about my disguised accessors I found out they're called properties. The idea is you can make a getter called a and a setter called a=, and it will look like there's a member a, but in fact it has a more complicated definition.
closed account (1yR4jE8b)
This thread makes my head hurt, why bother making C++ more complicated when languages like Python and Ruby do many of these 'features' in a much more elegant and simpler to define way.
Because I'm not making C++ more complicated, I'm thinking about a language that I could base off of C++/Java/and maybe some Python (which I'm learning right now)

Now, an interpreter would probably be the easiest and smartest way to go for now. How does one make an interpreter?
In interpreter, you parse the input just the same as a compiler would do (but statement-by-statement), and then simply execute it instead generating a code.

BTW: Your concept of a language is completely inappropriate for a person who doesn't have any experience with this stuff. C++ is already a nightmare to parse, and some of your extensions will make things much worse (custom operators? are you kidding me?). Why not start with some simple, very high level script language instead?
Last edited on
@PiMaster: take a look at those links I gave you (the first two ones). They show how to make a simple interpreter in Python.
I don't really like the cuatom operators idea myself, but I see what you mean. What would you suggest, Abramus?
Last edited on
As I said, start from the basics:
1) create an interpreter which is essentially a calculator only (evaluates formulas),
2) then add support for some simple types of variables,
3) then add support for some structural constructs (conditional expressions, loops, functions),
4) then you could improve what you have by adding more language features or libraries (classes, containers, other complex types, regular expressions, files, etc.).

What you will actually do after steps 1-3 depends on what you think is more important/interesting. Just don't try to add too many features at once. IMO, when you are learning, an incremental approach to coding is the best method. Even through you may later find out that you must change the fundamental design choices of your program.
Last edited on
I'm way behind on this thread, but to answer PiMaster's response to my post:

1. I suppose C++0x's decltype keyword is not technically needed by the compiler, but might assist the programmer in understanding what the function returns.
2. Dunno. I just don't like the "recursive instantiation with one fewer parameter" approach. It seems obtuse.
3. No. I want to be able to ask an object how many data members it has and what they are using metaprogramming.
4. Yes, I like the "extend" keyword syntax.
5. Like this: enum Color { red, blue, green }; Color c( red ); std::cout << str( c ); // Outputs "red" instead of "0"

6. Since #defines are evil, I prefer enums instead, which at least obey by scoping rules. That said, if I want to make a bitfield, I like to make mnemonics for the bits:
1
2
enum SomeRegister { WriteEnableLine = 1, ReadEnableLine = 2, SynchronousMode = 4 };
SomeRegister regValue = WriteEnableLine | ReadEnableLine | SynchronousMode;  // doesn't compile 


I'd like that line to compile without me having to write operator| (and operator& etc etc). I'd also like it to output similar to #5.

7. Not really. I want to make my own operators. operator@, operator[]( int, int ) for 2D matrices, etc.

8. Something like this (haven't given it too much thought):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

class Driver;
class Passenger;
class Mechanic;

class Car {
    public:  // Anyone can make these
        Car();

    public interface Driver:  // Only objects derived from Driver get these in the public interface
        bool StartEngine();
        void StopEngine();
        void ShiftGear( Gear newGear );

    public interface Passenger:
        void TurnOnRadio();
        void TurnOffRadio();

    public interface Mechanic:
        void PopHood();
};


Pages: 123