Skip to content

Comment on A nice, little known C feature: Static array indices in parameter declarationsparent

Comments

They don't really have a choice, do they? If you want to add features you can either: 1) make a new reserve word, possibly breaking existing code 2) reuse a reserve word in a new context.

Or you can add context-sensitive keywords, which are keywords only where it’s syntactically valid and identifiers elsewhere. Those two contexts are almost always mutually exclusive, and it’s obvious which one you’re in. ActionScript 3, though absolutely not a good example of language design in general, has a good example of this. You can say:

    public function get foo():int { return 5; }
But you can also say:
    var get:int = foo;

C# is up to about 25 of them, and it works well as long as you can resist the temptation to do silly things like

    var var = 1;
    var select = var.ToString();
    var from = from c in @select select c.GetHashCode();
(The @ thing, which tells the compiler, "This is an identifier and not a keyword", can help quite a bit in a pinch.)

C++11 also has them: override and final.

So:

  class Foo
  {
      virtual void bar() final;
  };
But:
  int final = 3;
So, for example, this is legal:
  class Foo
  {
      virtual void final() final;
  };

Larry Wall (author of Perl) used this as an argument for "sigils", that is, putting $/@/% in front of every variable.

http://stackoverflow.com/questions/1091634/why-do-perl-varia...

(I merely state this as fact and offer no judgement!)

Deleted my previous comment because it was wrong (I was saying that it didn't help with the names of subroutines). It appears you can even have subroutines named after keywords, but only as long as you put "&" in front of it when you call it:

    sub while
    {
        print "It works!\n";
    }

    &while();
I guess it is still the case that you can break perl code by adding keywords, if it collides with a subroutine that is called with the "&" symbol. Seems most code doesn't use "&" though, but it's a relatively quick fix.

Calling a sub with & has a special meaning, it exposes the current argument list @_ to the called sub. That's why you don't see it in most code.

I did not know that. Interesting. However, it only works if you call the sub without parentheses like this: &foo

Calling it with parentheses like &foo() would make @_ empty inside of foo. (Or if you said &foo("whatever") it would pass that as @_ instead.)

    sub while
    {
            print "@_\n";
            &foo();
    }

    sub foo
    {
            print "@_\n";
    }

    &while("a","b","c");
produces:
    a b c
    (blank line)
as the output, and
    sub while
    {
            print "@_\n";
            &foo;
    }

    sub foo
    {
            print "@_\n";
    }

    &while("a","b","c");
produces:
    a b c
    a b c 
as the output. At any rate, back to the original topic: it still doesn't prevent new keywords from potentially colliding. Oh well.

I prefer the objective-c method of putting @ in front of every keyword.

Well, I might be upset if this were true for all keywords.

    @static @inline @unsigned @int ilog2(@unsigned @int x)
    {
        @for (@unsigned @int i = 0; i < 32; i++)
            @if ((x >> i) == 0)
                @return i;
        @return 32;
    }
I'm a bit dizzy looking at that code, let me sit down for a moment.

I believe the @ is used only by the obj-c keywords and not the ones from C. So it'll be something more like this

    @autoreleasepool{
        for (int index = 0; index < 100; index++){
            int error = [MyObject performSelector:@selector(addCoolFilterToImage:)];
            if (error) {
                return 32;
            }
        }
    }

Yeah, that was kind of my point.

One better choice that comes to mind:

  void bar(int myArray[10+]);

That's not better. It's more confusing to see a symbol that's normally an operator than it is to see a keyword.

It's only confusing if you are a language parser. I doubt that anyone else would have any problem guessing what this means.

It looks like a syntax error to me. You can add numbers in array index brackets so a plus sign already has meaning there. Considering that a[10+] is just one character off from a[10++], it seems to me that this is just a bug waiting to happen.

It would be a syntax error. . . unless you add syntax for it.

As far as it being a bug waiting to happen, C already has plenty of traps like that - '=' vs '==', '&' vs '&&', and so on.

In terms of grammatical clarity, I shouldn't think it would be any more confusing than any other operators that have both unary and binary versions. By my count C already has three of those: '-', '&', '*'. The latter two are even examples where the unary meaning and the binary meaning are wholly unrelated.

Besides, it's a way of using + that is already well-established in everyday idiom. And there are semantically-related uses for + that are already well-established in computer languages, too - the Kleene +, for example, should be familiar to everybody.

In terms of how it would work for the grammar I realize this would be somewhat of a departure since it's repurposing a symbol that's normally an operator to be used in a manner that would be more like a keyword according to C syntax. . . but I think that's a detail that should be much more interesting to standards committees than it is to people who primarily just use the language. And in terms of the human factor I submit that it's much more workable than taking a word from the English language and repurposing it to mean something that's more-or-less the opposite of what it means in English.

"As far as it being a bug waiting to happen, C already has plenty of traps like that - '=' vs '==', '&' vs '&&', and so on."

And C programmers are already spending plenty of their time cursing the world because of those things. Let's not add more of that, shall we? ;)

I never ever had problems with it in C. I actually had a problem with it in another language (might have been a BASIC) where = was contextual, so one could do "a = 10" and then somewhere down the line "if x = 5 then". I used == and couldn't figure out what was wrong for nearly 5 minutes (I think it was recognising (or not) as an unexpected token).

= and == should have different meanings.

I also like how JavaScript has ===, although it is a little superfluous.

Interestingly PostgreSQL's pl/pgsql does that.

There are two operators, equality = and assignment :=

But where it is clear that assignment was meant, = is treated as assignment. this means you can:

    a = 5; -- exactly equivalent to a := 5 here
    if a = 6 then
        raise exception 'this should never happen';
    end if;
Interestingly this is entirely a Postgres-ism. Oracle's PL/SQL offers no such "feature."

The problem with the plus sign is that people have a natural assumption about what it means (that is, the addition). Changing that make things more confusing. At least, C programmer are used now to the fact that the static keyword can have strange and different meanings and another one is no big deal.

That looks nice, but I think it could be simply void bar(int myArray[10]), since C effectively ignores the number inside the first pair of brackets in a parameter list, they could have added some meaning to it. No need for another meaning for "static"

C reserves part of the namespace for the language or implementation, so they have a third way, which they've used for e.g. boolean types in C99. Make a new reserved word in the reserved namespace (either starting with __ or just _ followed by a capital letter) and then add a standard header to #define or typedef the unfriendly reserved word to something nicer for code that wants it.

Observe the differences between Managed C++ and C++/CLI to see how poorly this approach works in practice.

Knowing nothing about either, can you elaborate?

Managed C++ was chock full of __keywords for .NET memory management - like Apple's ARC in the worst case, except there were no good cases. While it probably was a clean superset of C++, it was painfully hideous.

CLI/C++, by which Microsoft replaced Managed C++, added new operators and keywords without much regard for backwards compatibility (=without underscores).

The implication being that people value code readability over __backward __compatibility. I have no data on the popularity of Managed C++ vs CLI/C++ though. I was only a fanboy because CLI/C++ looks awesome and I generally enjoy Herb Sutter's work, but then got sucked into the Appleverse.

Just adding __ keywords is not the approach I described, though. I described adding __keywords, and adding a standard header that redefines them into non-underscore keywords. This avoids breaking old code (it won't include the header) while allowing new code to use nicer keywords, if it wishes.

Right - I was just trying to provide context :) If there is anything in the Managed C++ -> CLI/C++ transition that is better than the ISO C approach, it is maybe the contextual keywords in CLI/C++ - something that can't be achieved with #define.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.