6

As a programmer, I often look at some features of the language I'm currently using and think to myself "This is pretty hard to do for a programmer, and could be taken care of automatically by the machine".

One example of such a feature is memory management, which has been automatic for a while in a variety of languages. While memory management is not that hard to do manually most of the time, doing it perfectly all the way through your application without leaking memory is extremely hard. Automation has made it easy again so that we programmers could concentrate on more critical questions.

Are there any features that you think programming languages should automate because the reward/difficulty ratio is just too low (say, for example concurrency)?

This question is intended to be a brainstorm about what the future of programming could be like, and what languages could do for us to let us focus on more important tasks, so please post your wishes even if you don't think automation is practical/feasible. Good answers will point to stuff that is genuinely hard to do in many languages, as opposed to single-language pet-peeves.

LordOfThePigs
  • 11,050
  • 7
  • 45
  • 69

16 Answers16

9

Whatever the language can do for me automatically, I will want a way of doing for myself.

  • 12
    I guess you code in Assembly? If not, you should give up Java, Python, C#, or whatever you use, since they do 99.99% of the tasks automatically for you. – Seb May 03 '09 at 14:51
  • 2
    +1, anything the computer does for you will be just right.. most of the time. Never *all* of the time. – gbjbaanb May 03 '09 at 14:56
  • 5
    No, I use C++ for most of what I do. But I have used languages like PHP, VB etc. on occasion and I think they could all be improved by allowing access to the lowerr level mechanisms that they must and do implement. I've never understood why GC'd languages can't support RAII (i.e. destructors) _and_ GC, for example. –  May 03 '09 at 14:56
  • So true. Always a good thing to be able to customize things *exactly* to your own requirements. +1 – Arve Systad May 03 '09 at 14:59
  • 2
    You'd have to explicitly declare (read-only) variables to be used in a RAII scheme. (Which is what happens with C#s `using` if you want) since the compiler cannot detect which objects are used only for the lifetime of the function and which get passed on. Also: Generational GCs will collect recently allocated objects pretty soon so the difference between RAII and explicit `using` blocks is not that big. – Christian Klauser May 03 '09 at 15:48
  • 1
    I was considering responding to the sentiment expressed here, but it's such a broad and pointlessly general answer that I'm not sure where to start. – Promit May 03 '09 at 16:33
  • @Promit Thank you for sharing that broad and pointlessly general response with us. –  May 03 '09 at 16:41
  • 1
    Python supports garbage collection and RAII. Unfortunately, the two do not mix well, because the interpreter can't clean up cyclic references when user-defined destructors are present (the `__del__` operator). – Tom May 03 '09 at 17:02
  • @SealedSun: The disadvantage of C#'s "using" is that the user must remember to apply it each time (i.e. the same problem that try/finally has). An ideal solution would be to encode this information *once*, in the type itself -- that way the user can't forget. However combining this with GC poses a few difficulties as discussed here: http://stackoverflow.com/questions/477399/does-java-support-raii-deterministic-destruction/477406#477406 – j_random_hacker May 04 '09 at 09:22
  • @Seb: Neil is not against helpful features being added to a language -- he's just saying that he doesn't want that to come at the cost of reduced flexibility. He just wants to be able to "opt out" if necessary. (I think...) – j_random_hacker May 04 '09 at 09:25
  • I'm surprised this answer got so many votes. Its far too general, and doesn't answer the question?? – andy May 25 '09 at 06:26
7

Concurrent programming/parallelism that is (semi-)automated, opposed to having to mess around with threads, callbacks, and synchronisation. Being able to parallelise for loops, such as:

Parallel.ForEach(fooList, item =>
{
    item.PerformLongTask();
}

is just made of win.

Certain languages already support such functionality to a degree, however. Notably, F# has asynchronous workflows. Coming with the release of .NET 4.0, the Parallel Extensions library will make concurrency much easier in C# and VB.NET. I believe Python also has some sort of concurrency library, though I personally haven't used it.

What would also be cool is fully automated parallelism in purely functional languages, i.e. not having to change your code even slightly and automatically have it run near optimally across multiple cores. Note that this can only be done with purely functional languages (such as Haskell, but not CAML/F#). Still, constructs such as example given above would be very handy for automating parallelism in object-oriented and other languages.

I would imagine that libraries, design patterns, and even entire programming languages oriented towards simple and high-level support for parallelism will become increasingly widespread in the near future, as desktop computers start to move from 2 cores to 4 and then 8 cores and the advantage of automated concurrency becomes much more evident.

Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • The recent versions of MATLAB began adding parallel options, and one of them is more-or-less exactly like the example you gave: PARFOR, a parallel for loop. It seems easy to use and can give significant speed-up. – gnovice May 03 '09 at 15:45
  • @gnovice: Yeah, it would make sense for MATLAB to have something like that. Not familiar with the package myself, but it's good to see that it's moving with the trend. – Noldorin May 03 '09 at 16:03
  • As I understand it, the whole "functional programming suits parallelism" argument is founded on the notion that arguments to a function can be evaluated in any order (and hence in parallel) without affecting the correctness of the results. That's certainly true for eager-evaluating languages like C and Perl. But (I think) Haskell internally treats every function as a function of one argument, using currying to build multi-argument functions -- doesn't that mean that function argument evaluation order actually *is* significant for Haskell and other lazily-evaluated languages? – j_random_hacker May 04 '09 at 09:34
  • 1
    @j_random_hacker: What you say is true, regarding arbitrary evaluation of arguments. I'm not at all familiar with the internals of Haskell, but whether lazy evaluation is used in certain situations shouldn't matter really. As long as all functions are pure, they should return the same result every time, which means that there's still no issue here. – Noldorin May 04 '09 at 13:05
  • @Noldorin: Thanks. But as I understand it, evaluation order does not influence the final value **provided evaluation completes** -- there are some computations that lead to an infinite sequence of reduction steps if evaluated eagerly, when they would not if evaluated lazily. So evaluating non-lazily risks turning a finite-time computation into an infinite-time one! (I think; perhaps someone else could correct me/make this more precise.) – j_random_hacker May 05 '09 at 12:22
  • @j_random_hacker: As far as I know, this still isn't a problem in F#. Infinite sequences when passed as parameters don't get evaluated until they are read from in the function body. Perhaps I am misunderstanding still? Nonetheless, you could be right with Haskell - I simply don't know enough about it. Indeed, if someone could explain things in another way perhaps that would help clarify the matter for the both of us. – Noldorin May 06 '09 at 01:33
5
exec("Build a system to keep the customer happy, based on requirements.txt");
Seb
  • 24,920
  • 5
  • 67
  • 85
5

In Java I would like a keyword that would make the entire class immutable.

E.g.

public immutable class Xyz {
}

And the compiler would warn me if any conditions of immutability were broken.

Fortyrunner
  • 12,702
  • 4
  • 31
  • 54
  • 4
    Wouldn't you want that to be an error, not a warning? – Zifre May 03 '09 at 15:21
  • 2
    This could be useful in many languages, not just Java, and could also be used to help automate concurrency. – LordOfThePigs May 03 '09 at 15:43
  • 3
    Immutability is a very strict condition. An object cannot be "somewhat" immutable. The `immutable` keyword is part of the contract between the user and the author of the class. If the author promises immutability, the compiler must enforce it. – Christian Klauser May 03 '09 at 15:53
  • Yes. I would want a compiler warning if any conditions were broken. – Fortyrunner May 03 '09 at 23:10
  • @ChristianKlauser: What exactly would such a keyword do? Some compiler and framework support for immutability would be useful, but mostly in scenarios where one would want "parallel" mutable and immutable types; at present, implementing such types requires a lot of repeated boilerplate code. – supercat Jun 28 '12 at 21:18
  • @supercat Good point and I have no easy answer. Maybe change the language so that you say Xyz xyz = immutable Xyz() and substitute immutable for new. I'm no language designer ;) – Fortyrunner Jun 28 '12 at 21:25
  • @supercat What I probably meant is to enforce that all fields of an `immutable` class need to be immutable as well. Not just `final` (`readonly` in C#). A final reference to a mutable list is not excatly immutable. - There are a number of problems with this approach, though: 1) It doesn't solve the boilerplate code issue. Something like Scala's `case class` would help 2) There are valid and useful examples of types that are immutable (towards it's clients) but have a mutable representation (as an implementation detail) – Christian Klauser Jun 29 '12 at 08:22
  • @ChristianKlauser: I would suggest that a prerequisite for useful immutability is a standardized means to distinguish data holders from entities; I would like to see data holders, including primitives, implement a generic interface with an `AsImmutable` method which would be expected to simply return `this` for objects where all nested data holders were already immutable, or create a new data holder whose nested data holders were replaced with `AsImmutable` equivalents. A useful companion interface, which would inherit from that one, would provide an `CloneAsMutable` method. – supercat Jun 29 '12 at 15:19
  • @ChristianKlauser: The necessary implementations of `IConvertableToImmutable` and `IConvertableToImmutable` for primitive types would be really easy. `Int32`, for example, should implement `IConvertableToImmutable.AsImmutable` to return `(object)this`, `IConvertableToImmutable.AsImmutable` to return `this`, and `IConvertableToImmutable.IsImmutable` to return `true`. Likewise for other primitives. That would allow the inclusion in such primitives in a type which was constrained to `IConvertableToImmutable`. – supercat Jun 29 '12 at 15:26
5

In Java, create beans less verbosely.

For example:

bean Student
{
    String name;
    int id;
    type1 property1;
    type2 property2;
}

and this would create a bean private fields, default accessors, toString, hashCode, equals, etc.

flybywire
  • 261,858
  • 191
  • 397
  • 503
4

Concurrency. That was my main idea when asking this question. This is going to get more and more important with time, since current CPUs already have up to 8 logical cores (4 cores + hyperthreading), and 12 logical cores will appear in a few months. In the future, we are going to have a hell of a lot of cores at our disposal, but most programing languages only make it easy for us to use one at a time.

The Threads + Synchronization model that is exposed by most programming languages is extremely low level, and very close to what the CPU does. To me, the current level of concurrency language support is roughly equivalent to the memory management support in C: Not integrated, but some things can be delegated to the OS (malloc, free).

I wish some language would come up with a suitable abstraction that either makes the Threads + Synchronization model easier, or that simply completely hides it for us (just as automatic memory management make good old malloc/free obsolete in Java).

Some functional languages such as Erlang have a reputation of having good multithreading support, but the brain-switch required to do functional programming doesn't really make the whole ordeal much easier.

LordOfThePigs
  • 11,050
  • 7
  • 45
  • 69
  • Take a look at the OpenMP stuff. It might bend your brain a little with a different approach to parallelization that doesn't include some an emphasis on threading. It changed my perspective on the subject. Erlang gains a lot of its power from not having to deal with synchronizing shared data not for its "multithreading" support. – D.Shawley May 03 '09 at 15:44
  • Yes, synchronizing sounds like something that should be automatic. I mean, normally no-one wants their data to get corrupt anyway. It is just tedious to try to avoid it by coding myself. – Silvercode May 25 '09 at 06:43
4

.Net:

A warning when manipulating strings with methods such as Replace and not returning the value (new string) to a variable, because if you don't know that a string is immutable this issue will frustrate you.

Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
  • Agreed. This issue has frustrated me when working with dates also. Maybe if you could specify a class as immutable (as Fortyrunner suggests for Java but would also be useful for .NET) there could be a warning in this situation. – Meta-Knight May 03 '09 at 15:52
  • I'd add this to Java as well. – Seb May 03 '09 at 15:56
  • Interesting. Would be hellishly difficult to implement in the language compiler. But that would be an interesting metric for profilers. – Christian Klauser May 03 '09 at 15:57
  • 1
    I'm pretty sure tools like ReSharper will do this for you, and possibly the code analysis tool in Visual Studio as well. – Rex M May 03 '09 at 16:34
  • If I'm not mistaken, ReSharper doesn't give a warning about the Replace method issue – Andreas Grech May 03 '09 at 23:06
2

In C++, type inference for variable declarations, so that I don't need to write

for (vector<some_longwinded_type>::const_iterator i = v.begin(); i != v.end(); ++i) {
    ...
}

Luckily this is coming in C++1x in the form of auto:

for (auto i = v.begin(); i != v.end(); ++i) {
    ...
}
j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
  • 1
    How is it going to work out you want a const iterator? –  May 03 '09 at 14:58
  • This is my worry too Neil. I don't expect that the implementation is going to do semantic overloading correctly. This is going to be an interesting addition to the language for sure. – D.Shawley May 03 '09 at 15:01
  • 2
    My question was slightly facetious - I expect it will give you an iterator based on the const'ness of 'v'. But if I really want a const iterator to a non-const object, I will have to ask for it, as now. I don't mid the 'auto' idea, but only because I can override it. –  May 03 '09 at 15:10
  • 2
    They're also adding new names for the const_iterator versions of being and end, cbegin and cend, so: for(auto i = v.cbegin(); i != v.cend(); ++i) { ... } – Logan Capaldo May 03 '09 at 15:11
2

Coffee. I mean the language is call Java - so it should be able to make my coffee! I hate getting up from programming, going to the coffee pot, and finding out someone from marketing has taken the last cup and not made another pot.

kenj0418
  • 6,688
  • 2
  • 27
  • 23
2

Persistence, it seems to me we write far too much code to deal with persistence when this really should be a configuration problem.

Tony Edgecombe
  • 3,860
  • 3
  • 28
  • 34
  • Persistence should be a configuration problem, but some platforms that assist in that are highly complex themselves too. Then we would need persistence configuration automation to ease things further. – Silvercode May 25 '09 at 06:50
1

In C++, enum-to-string.

In Ada, the language defines the 'image attribute of an enumerated type as a function that returns a string corresponding to the textual representation of an enumeration value.

C++ provides no such clean facility. It takes several lines of very arcane preprocessor macro black magic to get a rough equivalent.

  • Java enums are really powerful and provide that functionality (also each member of the Enum has its own class, so that allows for enum wide functions that can be implemented differently for each member. Really cool stuff!) – LordOfThePigs May 03 '09 at 15:22
  • +1. It's surprising how often I've wished for this simple feature. – Logan Capaldo May 03 '09 at 15:23
  • The problem in C++ (and C) is that enums values do not have to be distinct and can vbe treated as integers Expecting the compilerv to differentiate non-distict values would involve a largish overhead. –  May 03 '09 at 15:49
  • There would be no more overhead than expected (in C++ at least), each enum is a distinct type. – Logan Capaldo May 04 '09 at 02:56
  • The type is distinct, the values need not be. –  May 04 '09 at 08:18
  • They could expand the RTTI to support more information, this among others, without that big of an overhead really. Look how small .NET executables are (tens of Ks) and they have FULL reflection information already built in. – Blindy May 25 '09 at 15:48
0

For languages that provide operator overloading, provide automatically generated overloads for symmetric operations when only one operation is defined. For example, if the programmer provides an equality operator but not an inequality operator, the language could easily generate one. In C++, the same could be done for copy constructors and assignment operators.

I think that automatically generating one-side of a symmetric operation would be nice. Of course, I would definitely want to be able to explicitly say don't do that when needed. I guess providing the implementation of both sides with one of them being private and empty could do the job.

D.Shawley
  • 58,213
  • 10
  • 98
  • 113
  • FWIW, Haskell does this. – Logan Capaldo May 03 '09 at 15:14
  • Yup... there is always another language that does a few more nice things. Eiffel has a number of features that I really like as well like renaming and the ability to specify exactly which operations you want to inherit. In the end, I'll still stick with C++ for my general programming tasks. – D.Shawley May 03 '09 at 15:37
  • Yea Eiffel's code contracts are cool too, but in my opinion little more than glorified `asserts`. Code contracts, however, become very interesting in the context of static verification. – Christian Klauser May 03 '09 at 15:55
0

Everything that LINQ does. C# has spoiled me and I now find it hard to do anything with collections in any other language. In Python I use list comprehensions a lot, but they are not quite as powerful as LINQ. I haven't found any other language that makes working with collections as easy as in C#.

Zifre
  • 26,504
  • 11
  • 85
  • 105
0

In Visual Studio environment I want "Remove unused usings" to run across all file in the project. I find it a significant loss of time to have to manually open each individual file and call this operation of a file basis.

User
  • 30,403
  • 22
  • 79
  • 107
0

From a dynamic languages perspective, I'd like to see better tool support. Steve Yegge has a great post on this. For instance, there are lots of cases where a tool could look inside various code paths and determine if the methods or functions existed and provide the equivalent of the compiler smoke test. Obviously, if you're using lots and lots of truly dynamic code, this won't work, but the fact is, you probably aren't, so it would be pretty nice if Python, for instance, would tell you that .ToLowerCase() wasn't a valid function at compile time, rather than waiting until you hit the else clause.

s = "a Mixed Case String"
if True:
   s = s.lower()
else:
   s = s.ToLowerCase()
easel
  • 3,982
  • 26
  • 28
0

Easy: initialize variables in C/C++ just like C# does. It would have saved me multiple sessions of debugging in other people's code.

Of course there would be a keyword when you specifically do not want to init a var.

noinit float myVal; // undefined
float my2ndVal;     // 0.0f
Enigme
  • 31
  • 3