top | item 3341109

How would you change your favorite programming language to make it better?

46 points| raganwald | 14 years ago |blog.fogus.me | reply

95 comments

order
[+] raganwald|14 years ago|reply
I recall being asked a variation: Given your two strongest languages, which features from each one do you miss when programming in the other, and why?

I find it interesting to that the question "Which features do you miss when using a language?" is not equivalent to "Which features would you add to the language?" The former feels like it speaks to my vision of my personal style, while the latter can be construed to include all of the pragmatic concerns of adoption, such as features alleged to assist large teams of indifferent programmers or features that would break backwards compatibility.

[+] fogus|14 years ago|reply
I like to ask both, but the question in the post is much better for generating multifaceted followup discussions much in the vein of your points.
[+] frou_dh|14 years ago|reply
C# is pretty nice though perhaps not my favourite language. One thing I found nuts about it is that you need to check whether anything is subscribed to an event before raising it. If you raise an event that nothing currently cares about, you get a NullReferenceException!

So if a tree falls in the forest with no one around then the universe implodes.

[+] kmontrose|14 years ago|reply
Anders isn't a huge fan of events, apparently (http://channel9.msdn.com/Shows/Going+Deep/Anders-Hejlsberg-Q..., around 56:00). I always just initialize events with an empty delegate in personal projects, which is very much the wrong thing to do but it saves me the null ref headache.

I would personally like to see `var` available in private and internal class members (properties, fields, and methods). There's a lot of pointless repetition that could be eliminated. (Obviously, you want to be explicit about the interface defined by a class' public members).

I also consider Tuple<> a missed opportunity, I'd like to see another whack taken at it that veers closer to structural typing. The existing tuple type is very unwieldy once you start returning or storing it, and I feel a pretty good alternative could be built on the principles of `var` and anonymous types.

Picturing something like:

  static tuple SomeMethod(){
    return new tuple { SomeNumber = 1, SomeString = "hello" };
  }

  static void Main(){
    var t = SomeMethod();

    Console.WriteLine(t.SomeNumber + " "+t.SomeString);
  }
Whereas Tuple<> forces you to write that with ItemX scattered around.
[+] city41|14 years ago|reply
This isn't true in VB.NET (it implicitly checks for null for you). But a common way to resolve this in C# is to initialize your event with delegate {}. So that way at least that no-op is always subscribed.
[+] strager|14 years ago|reply
JavaScript.

Kill the "new" operator. Make prototypes less magical (i.e. use something like `Object.create` to construct).

Secondarily, kill getters and setters. (That includes `Array#length`.) I want code and data, not code, data, and code which pretends it's data.

I don't mind the JavaScript syntax much (`function () {` isn't that difficult to type or scan through after you've dealt with it for a while). I'm fine with the small core object and function set. I'm fine with the DOM (except the getters/setters part). I'm okay with `Object.prototype.hasOwnProperty.call`; that can be swept away into a function. Just don't make me write code which looks like statically-typed classical OO spaghetti. I want dynamic prototypal functional spaghetti. =]

[+] squidsoup|14 years ago|reply
What do you dislike so much about constructors? I find a nice pattern using require.js (AMD) is to return a constructor function in a module, allowing the calling code to consume the module with:

var module = new Module();

[+] ericb|14 years ago|reply
I would add coffeescript-style instance variable setting to ruby method definitions like so:

  def initialize(foo, bar, baz)

    @foo=foo

    @bar=bar

    @baz=baz

  end

Would now be:

  def initialize(@foo, @bar, @baz)

  end

This would save hundreds of lines of code in large programs-- lines which could no longer be a source of typos or errors.

Oh, also I'd make binding_of_caller work.

[+] Miky|14 years ago|reply
I was under the impression that you could already do that in Ruby, although I don't use it much and very well could be wrong.

Edit: Never mind, I just tried it and got an error.

Weird. I could have sworn I'd seen it done somewhere.

[+] raganwald|14 years ago|reply
That falls out of destructuring, so if you order def foo(@bar) now, we'll throw in a free

  {@kbar, fu: @bar, blitz: [@first, @rest...]} = someHash
At no extra charge.
[+] orangecat|14 years ago|reply
That would be my answer for Python as well. Interesting that both languages have the same flaw, when they're normally very good about eliminating boilerplate.
[+] tomjen3|14 years ago|reply
I will take on the challenge of Lisp then.

First it needs to have a much bigger standard library, much like Java.

Second it needs a really effective foreign function interface possibly one which allows direct call to C++. This enables the programmer to take advantage of all the libraries written in C or C++ without having to write C or C++. In particular it allows using wxWidgets, gtk, qt and native win32/64.

Finally I would fix the output of the compiler (having an image is nice, combining it with the compiler to produce an executable makes sense) since (at least for SBCL) the output is 50mb for Hello World (granted, it doesn't grow much after that).

[+] baddox|14 years ago|reply
Which Lisp implementation are you referring to? I was under the impression that some Common Lisp implementations have pretty huge standard libraries.
[+] daemin|14 years ago|reply
I'd say that there needs to be at least a standard or near canonical implementation of the toolset.
[+] comex|14 years ago|reply
In C:

- Allow labels to be followed by variable declarations or the end of a block.

- Change switch to make each case its own block, and not fall through by default (but add a keyword to explicitly fall through).

- Support labeled break and continue (often much clearer than goto; sometimes separating the inner loop into its own function is clearer than either, but not always).

- Change the precedence of & and |.

- In do/while, evaluate the loop condition within the block's scope:

    do { int a = ...; } while(a);
- Allow variable declarations anywhere in an expression: not just

    while(int a = ...)
as in C++, but even

    while((int a = ...) == 0)
or

    getvalue(&(int a));
- Standardize some GNU extensions such as ({ }), void pointer arithmetic, __attribute__((pure)), and __builtin_unreachable().

- Standardize visibility.

- Standardize Apple blocks.

- Tuples, with quick unpacking:

    {int a, bool ok} = func();
- Explicit control of may-alias, something more powerful than restrict.

...This is fun.

[+] neilk|14 years ago|reply
It's a good question. I wish I had a favorite programming language, though. I think if you spend more than ten years in the business and you still are in love with a particular tool, you probably haven't really done anything big, or you haven't ever looked around to see how other people do things.

JavaScript is probably the language I hate the least. And I'd make some of the CoffeeScript syntax standard, and maybe bring in some concepts to keep spaghetti callbacks under control.

[+] fogus|14 years ago|reply
That's an interesting generalization there. In my time I've encountered many kinds of programmers. Some could create amazing things despite their tool or language. Likewise, there were many who created amazing things with the help of their favorite tools or langauges. It's not wrong to have a favorite tool. It's natural. However, it might not be a great idea to think solely in terms of the tool; limitations and all. This is the spirit of the question.
[+] rayiner|14 years ago|reply
> I think if you spend more than ten years in the business and you still are in love with a particular tool, you probably haven't really done anything big, or you haven't ever looked around to see how other people do things.

Overgeneralization. It's like nice looking cars. Just because you love a classic Shelby Mustang doesn't mean you can't acknowledge there are other good tools out there.

After years of programming professionally in C++ and occasionally Python, there is still something about the design of Common Lisp that I love. It's like using a Mac--the attention to detail evidences an obvious good taste that I rarely see in other languages or their libraries.

[+] radagaisus|14 years ago|reply
Today, development means more and more work with external APIs, Open Source projects, and general code written by others. A huge time waster is coming back to a piece of code, and finding this: `foo(bar, true, false, true)`. Now you need to go and check the documentation of whatever you're using. IDE solve this half way with auto-complete. We sometimes use ENUMS for the boolean flags, and write yelling code `foo(bar, YES, TOTALLY, DX9_D3D_HWIN_OK_BOOL_FLAG)`. (I hate your guts DirectX). But a verbose code with argument names makes it really easy to create DSLs. Ruby wins over Python here.

`some_function arg1: val1 arg2: val2` with parentheses just to solve ambiguity.

On another note, I always did not understand why there's no For..Else construct, but then I met python.

[+] DasIch|14 years ago|reply
If you are using Python, you can call any function with keyword arguments e.g foo(bar, something=True, whatever=False, blubb=True) even if it is defined using positional arguments like foo(bar, something, whatever, blubb)
[+] vq|14 years ago|reply
Haskell could really need a better record syntax. I really don't know how that should be designed though...
[+] strager|14 years ago|reply
What's wrong with `data Foo = Bar | Baz { a :: Int }` ? I'm not a day-to-day Haskeller, but I find the record syntax very nice and succinct.
[+] leftnode|14 years ago|reply
I ask this question as well. I work mostly with PHP developers and it's telling most of them don't have an answer or only say "consistent function argument order".

If you claim to have 7+ years using a language, surely there's a list of things you could add to make it better.

I think it's standard in the PHP ecosystem though.

[+] boyter|14 years ago|reply
Oddly enough in PHP the things I find most annoying aren't the inconsistent method names or parameter order. I can live with those as the documentation is pretty good and most IDE's give me a hint as to what its expecting.

The thing I find most annoying is being unable to pop the first element off an array when its returned and that when you do things like array_map it dosn't work with a method inside the same or other classes,

EG

$this->method()[0];

array_map($this->doSomething, $array);

[+] hendzen|14 years ago|reply
Java isn't my favorite language, but since I use it fairly often I would love to have functions be first class.
[+] sage_joch|14 years ago|reply
The first thing I'd change about Java is to do away with checked exceptions. Yours would be a close second, though.
[+] frio|14 years ago|reply
I'd add "with" statements. No more:

  Closeable dbConnection;
  try {
    dbConnection = CloseableFactory.getConnection();
    doWork(dbConnection);
  } catch (CloseableException ex) {
    // log it or whatever
  } finally {
    // the really annoying, stupid, crufty boilerplate bullshit
    try { 
      if (dbConnection != null) 
        dbConnection.close();
    } catch (CloseableException ex) {
      // it's probably already closed
    }
  }
Instead, it'd just be

  with (Closeable dbConn = CloseableFactory.getConnection()) {
    doWork(dbConn);
  }
(Assuming the "with" statement eats errors relating to the instantiation/closing of the Closeable, anyway). Bliss. And I know there's stuff like Google Guava's Closeables.closeQuietly(conn);, but still, a with statement would be awesome.
[+] tikhonj|14 years ago|reply
You, and everybody who has responded to you so far, should check out Gosu[1]. It takes Java syntax and (among other things!) adds first-class functions and lambdas, adds a with statement (called "using") and gets rid of checked exceptions.

[1]: http://www.gosu-lang.org

In addition to solving all the problems people here are complaining about, it adds type inference, mixin-type-things, a superior collections interface (map and friends) and a bunch of other nice features.

However, the best bit (from a Java developer's perspective) is that it looks and behaves almost exactly like Java, just improved. Going from Java to Gosu is trivial but very nice.

[+] quanticle|14 years ago|reply
I would add query expressions (like list comprehensions from Python or LINQ).
[+] spatten|14 years ago|reply
Unless I'm talking about Erlang, my answer is almost going to be "I really miss Erlang's pattern matching". (I know it's not exclusive to Erlang, but that's where I learned it).

My dream language right now would be something with the expressiveness of Ruby and the concurrency abilities and pattern matching from Erlang.

Hmm. I think I need to go look at where Reia (http://reia-lang.org/) has got to since I last looked at it.

[+] Swizec|14 years ago|reply
If I could make one change to one language I currently use a lot, it would be to add implicit returns to javascript functions.
[+] baddox|14 years ago|reply
You just mean to make a function return the value of its last expression, right? That seems like an extremely small feature. Do you just prefer it as a matter of taste, or are there larger consequences of implicit returns that I'm not thinking of?
[+] 3pt14159|14 years ago|reply
I'd combine certain ruby-isms into python, but retain pythons speed and readability. Specifically I would default dicts to return nil unless typed as strict dicts (opposite of current practice). I think the way kwargs are handled is cool and would move into Ruby. I like detatched functions way more in Python. I prefer the consistency in pass by ref vs pass by value in python, whereas in Ruby I'm never 100% sure. I like how both languages can communicate with C very easily.

Edit:

In python 0 should not equal False and 1 should not equal True. This has hit me a couple times and it is really annoying. Furthermore, 0 should be cast to True, as in Ruby. Only None and False should be cast to false.

[+] CyruzDraxs|14 years ago|reply
I'm a Javascript user. The list of things I'd change is enormous. A few of the biggest things though, is making better object looping; it's annoying having to check each property to see if it's on the object itself or it's prototype. It'd also be nice to have a build in extend/include system, rather than having all these different custom ones people use. Put jQuery and Underscore on the same page and you have two different implementations of object extension. Seems like kind of a waste of code.
[+] strager|14 years ago|reply
On object looping:

    Object.keys(obj).forEach(function (key) {
        var value = obj[key];
        // ...
    });
Not the best thing, but it works in less lines than:

    var key;
    for (key in obj) {
        if (!Object.prototype.hasOwnProperty(obj, key) {
            continue;
        }

        var value = obj[key];
        // ...
    }
Plus, it avoids the async-function-in-a-loop problem (which is why I rarely use C-style `for` loops or `for-in` loops now).
[+] Someone|14 years ago|reply
Not quite favourite, and not a language change, but in C, C#, Java, I would change the IMO ridiculous idea to write CONSTANTS in uppercase.

I understand that preprocessor macros have to stand out because they have different semantics (arguments might be evaluated multiple times, use of ## to fabricate tokens, etc), but i do not think

- In C, macro names are by convention uppercase

- in C, one used to use macros to define constants

- hence, in each C-inspired language, constant names must, by convention be uppercase

is a valid syllogism.

[+] mwsherman|14 years ago|reply
Null coalescence in C#. Reference types must be checked before trying to access their members. So you’ll see a lot of:

if (mything != null && mything.User != null) { Do.Something(mything.User.Name); }

I’d like to write:

Do.Something(mything?.User?.Name);

It’s syntactic sugar, but would greatly improve readability, and a compiler could do it with no change to the runtime.

[+] noamsml|14 years ago|reply
I'd take python and add optional variable declaration and flexible explicit typing constraints (a variable can be declared as either having certain methods returning a certain type, or as being of a set of types, or as being of any type, but all type declarations are optional) that are verified at compile time.
[+] boyter|14 years ago|reply
If type hinting (and checked at parse/compile time) was in Python it would solve my biggest complaints with the language. Yes I know you can write unit tests to do it but frankly that's busy work I shouldn't have to worry about.
[+] DasIch|14 years ago|reply
You can't have optional variable declaration and compile time verification. Either you have optional variable declaration and checking is performed and runtime or you get compile time verification and make the language static.
[+] tjpick|14 years ago|reply
I'd take python and make all the people who write libraries for it write proper documentation.
[+] itmag|14 years ago|reply
Intellisense.

Not a huge fan of C# but that part is awesome.

[+] micmcg|14 years ago|reply
Intellisense isn't a feature of the language, its a feature of the IDE you are using.
[+] Sandman|14 years ago|reply
How exactly is intellisense a feature of a language?