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.
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.
Seriously, it's been an issue when I've been trying to collaborate with others on a side project. We had the question of what language to start with. Some of the interested contributors were Python consultants and insisted that not only was Python the best language, but that Python was the best community, and Python people were the best and most virtuous people. (It is a kind of activist do-gooder project, which is why that person thought this was relevant.)
This sort of opinion seems asinine to me now, and it hurts especially because I used to be one of those guys around 1998-2000 or so -- except, for Perl.
The question of what language to start with kind of paralyzes me now, because when I consider what we'll want a few months in, I see this field of leg-hold traps we're going to step in. In all directions. I almost wish I had less experience and foresight (or more courage, take your pick).
I do think that Python is the best language, but I've worked with some truly terrible languages, so I'm not going to spend any time trying to convince someone that we should use it on a program. All I ask from a programming language is a type system, arrays, functions, and scoping. Some sort of notion of class/class methods is nice, as is a few hash/set-type containers to supplement the default array container. Having done "high-level" programming in languages that had none of these features, I'm pretty content with whatever is handed to me to work with.
> 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.
My friend Alex Graveley also has a totally different way of doing this, and a lot more, that uses the standard but not often implemented 'yield' keyword to create an Erlang-style process model, hence "Er.js":
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.
I used to think, "Here's a library with a README on the side to get you started." Now I think, "Here's an essay with a library on the side to get you started."
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.
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.
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.
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.
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.
This looks very nice. From what I've seen, the only thing I'd change is the way it deals with exceptions.
Specifically, I'm not very happy with this way of throwing
exceptions (example taken from Gosu documentation on exceptions [1]):
throw "x does not equal zero"
and then later chatching them like this :
catch( e ) {
if( e == "x equals zero" ) { return( e + " handled
locally." ) }
I want to be able to specify the exact type of the exception, and catch them based on their type, instead of having to throw a generic error and then check using "if" statements whether it's expression is equal to a particular String or not. If I understood correctly, this is what Gosu is actually doing, right?
Well, this is not exactly what I want. You can catch exceptions by type, but only from some code (for example, a Java library) that actually throws different types of exceptions. In Gosu, I can't throw them by type, at least from what I've seen. I can only throw some generic type of exception (or is it an error? Or something else that implements Throwable? Who knows, Gosu doesn't tell you anything about that) that contains some expression (a String literal), and then anybody who wants to catch it, needs to know that exact expression in order to catch the exception.
The more I think about it, the more terrible this looks. I can't even specify to the users of my code which exceptions they should look after (because, it seems, Gosu doesn't allow the throwing of checked exceptions and the 'throws' clause). So if I write some kind of library in Gosu, and if that library is throwing exceptions, I'm basically forcing the users of my library to catch this generic exception (or whatever it is), then put a breakpoint in the catch block and every time something gets caught inspect the expression, hoping that if they test long enough they'll find all of my expressions. Then, they need to write code that covers all the possible cases (a bunch of "if" statements).
I sincerely hope that I somehow completely misunderstood what Gosu is trying to do here, because otherwise this is just a terrible solution. That would be a real shame though, because, other than this, I honestly like the language.
I think you can throw anything, including whatever sort of exception you could want.
However, the real idea is that you should not use exceptions for anything expected like IO issues. Exceptions are meant to signify errors that could not be handled--unlike in Java, you shouldn't use exceptions for control flow.
The real issue is one of semantics--in Java, one concept (exceptions) is used to represent two do disparate things: signal unexpected errors (runtime exceptions) and manage expected conditions (checked exceptions). A lot of people do not like checked exceptions and think exceptions should only really be used for the former case. Thus the lack of checked exceptions is a feature rather than a bug; moreover, it is a feature other people in this thread have already requested.
So, the potentially annoying answer is that people using your library should not expect particular exceptions--that is not what they should be used for in Gosu. Coincidentally, this is very similar to how JavaScript deals with exceptions, and I have had no issues there at all.
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.
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,
Yes, neither is intuitive. And the syntax sucks. And it's not as easy to read (except sometimes where a method returns a tuple; `list` is wonderful there!). But it's certainly possible...
There are plans for this[1] but it seems to be on/off - currently the RFC is 'accepted' - not sure when it's being introduced though (I believe there was a patch). It's certainly something I want, I come across this all the time.
Definitely (and as other posters have mentioned, it is in/out of the works). I'd expect some developers applying for a senior development position to have similar opinions.
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.
There is nothing wrong with the definition syntax. The only problem I have with those are the "namespace-pollution" problem where you must have them in a separate module to isolate field names (which is kind of a small issue to me).
What I have a bigger problem with is the syntax for updating fields is so clumsy. It doesn't go very well with the rest of the language and I usually end up writing helper functions for updating specific combination of fields.
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. =]
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:
The problem with constructors is that they are completely redundant and introduce unnecessary complexity. In javascript, it hardly ever makes sense to call a constructor (e.g. a Function, Array, etc.) without the 'new' keyword, likewise it makes almost zero sense to call a normal function with the 'new' keyword. So, instead of the requiring the programmers to know which function is a normal function and which is a constructor, we could simply call all the functions normally (without 'new'), and have the function return a new object (if necessary). Kinda like what python does.
Right. The "new" keyword is never necessary and is usually actively counterproductive. In Java, "new Hammer()" must allocate a new object and it must be exactly a Hammer instance, and to work around those limitations we get the joy of AbstractHammerFactoryFactory. In Python, "Hammer()" can return an existing object and it can be a subclass of Hammer; callers don't need to know the details.
In Java, it's a bit different. There, classes (`new Hammer()`) and function (`Hammer()`) are orthogonal concepts that cannot be mixed, while in JavaScript, they are one and the same thing.
In addition, AFAIK there are some funny issues in JavaScript when a constructor function returns an object that is not the object bound to `this` (i.e. the new object created by the `new` keyword).
Exactly. This is my problem with the `new` syntax.
There are still other problems (in my opinion) with the concept of constructor functions. It basically boils down to mixing data (prototype) and code (constructor funciton).
Side-effects in a constructor are a big no-no. However, if you want side-effects, you're forced to write your code in a different style.
As a (really bad) example, you have an Enemy "class" which must know about enemies adjacent to itself at creation time.
Without side-effects (using `new`):
var enemy = new Enemy(enemyList);
enemyList.push(enemy);
// Now enemy is inside of enemyList,
// but it's not enforced. I find this
// method prone to mistakes.
With side-effects (using `new`):
var enemy = new Enemy(enemyList);
// Now enemy is inside of enemyList;
// I wouldn't expect that postcondition!
And without constructors, but with side-effects:
var enemy = enemyList.createEnemy();
// or
var enemy = createEnemy(enemyList);
// Now enemy is inside of emptyList
The problem here is that an enemy must be part of a list. The classical OO solution is to use constructor parameters. Ideally, I'd just have a function to deal with creation and adding it to the list (like `createEnemy`).
In ES5, `enemyList.createEnemy` could be written like this:
var enemy = Object.create(Enemy.prototype, {
enemyList: { value: this } // Ugh!
});
this.push(enemy);
Enemy.call(enemy); // Necessary evil if you use standard JS "classes"
return enemy;
I'd much prefer something like:
var enemy = enemyProto { enemyList: this }; // Basically binds the object literal with the enemyProto prototype, returning the modified object.
this.push(enemy);
// enemy ctor logic here; e.g. Enemy.call(enemy) as above
return enemy;
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).
My favorites were C, Postscript, NewtonScript, and Objective-C. Objective-C improved C. A compiled F-Script with some way to drop back down to C would be great. NewtonScript needs a new implementation and a switch from the Pascal-like syntax.
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.
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.
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.
Anonymous types can only be used for local variables. They cannot be returned from procedures, passed as parameters, or assigned to fields.
Tuples, on the other hand, are full-fledged generic classes. That introduces an advantage in that they're first-class entities which can be used anywhere. But it introduces a couple disadvantages, too: There's a separate class implementation for each number of elements, and implementations are only provided for up to 7 elements plus an 8th weird kludge for supporting more. And having the tuple's "official name" be Tuple<$ARBITRARY_LIST_OF_TYPES> is not only cumbersome, but also misses an opportunity to do a better job of communicating semantics.
What's going on here? Are they equivalent? What are they being used for? What's up with the different types for Item2, are they equivalent? For that matter, what about Item3? Sure it's got the same type, but we've really got no idea what it's being used for. And since it's being implemented as a plain old generic class, there's no class definition on which you can lay some documentation about this stuff. Just a bunch of disembodied type declarations all more-or-less equivalent to each other.
You know that phase in a lot of beginning programmers' careers where every variable is named foo1, foo2, etc? This is in many ways the same thing, only codified and enshrined by the .NET Framework designers. Oh, and the word's "Item" instead of "foo".
Practically speaking, it means that Tuple's crippled. Sure, technically you can use it for anything. But if you're the kind of person who likes maintainable code, you really don't want to be using it for anything but the most trivial cases. You certainly shouldn't be using it in any interfaces that other people are going to have to work with.
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?
While you're right that intelligent autocompletion is not a feature of a programming language, clearly it's much easier to create one for some languages than for others. It's not a coincidence that there's still aren't any really usable intelligent autocompleting editors for JavaScript but there is a number of very high quality ones for C# and Java.
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.
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)
Yeah, I know, but in Ruby you can drop the parentheses. And in 1.9+ instead of `:something => 'value' you can write just `something: 'value'`. Python: `make('coffee', sugar=2, with='poison')`. Ruby: `make 'coffee', 2, with: ['poison']`. I prefer Ruby's style but it's still lacking.
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.
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.
CoffeeScript implements def foo (@bar, @blitz) using destructuring assignment, a general facility that applies to assignment statements, not just function calls.
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.
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
Adopting Ruby-style code formatting as a common idiom for Scala and Java, where I'd eliminate the usage of curly braces and instead use indentation for code blocks.
99 comments
[ 2.8 ms ] story [ 160 ms ] threadJavaScript 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.
Seriously, it's been an issue when I've been trying to collaborate with others on a side project. We had the question of what language to start with. Some of the interested contributors were Python consultants and insisted that not only was Python the best language, but that Python was the best community, and Python people were the best and most virtuous people. (It is a kind of activist do-gooder project, which is why that person thought this was relevant.)
This sort of opinion seems asinine to me now, and it hurts especially because I used to be one of those guys around 1998-2000 or so -- except, for Perl.
The question of what language to start with kind of paralyzes me now, because when I consider what we'll want a few months in, I see this field of leg-hold traps we're going to step in. In all directions. I almost wish I had less experience and foresight (or more courage, take your pick).
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.
https://github.com/jashkenas/coffee-script/issues/1710
My friend Alex Graveley also has a totally different way of doing this, and a lot more, that uses the standard but not often implemented 'yield' keyword to create an Erlang-style process model, hence "Er.js":
http://beatniksoftware.com/erjs/
But you might want both TameJS and Er.js for different applications.
You just don't get all the typeerors.
[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.
Specifically, I'm not very happy with this way of throwing exceptions (example taken from Gosu documentation on exceptions [1]):
and then later chatching them like this : I want to be able to specify the exact type of the exception, and catch them based on their type, instead of having to throw a generic error and then check using "if" statements whether it's expression is equal to a particular String or not. If I understood correctly, this is what Gosu is actually doing, right?[1] http://gosu-lang.org/doc/wwhelp/wwhimpl/js/html/wwhelp.htm#h...
[1]: http://gosu-lang.org/doc/wwhelp/wwhimpl/js/html/wwhelp.htm#h...
The more I think about it, the more terrible this looks. I can't even specify to the users of my code which exceptions they should look after (because, it seems, Gosu doesn't allow the throwing of checked exceptions and the 'throws' clause). So if I write some kind of library in Gosu, and if that library is throwing exceptions, I'm basically forcing the users of my library to catch this generic exception (or whatever it is), then put a breakpoint in the catch block and every time something gets caught inspect the expression, hoping that if they test long enough they'll find all of my expressions. Then, they need to write code that covers all the possible cases (a bunch of "if" statements).
I sincerely hope that I somehow completely misunderstood what Gosu is trying to do here, because otherwise this is just a terrible solution. That would be a real shame though, because, other than this, I honestly like the language.
However, the real idea is that you should not use exceptions for anything expected like IO issues. Exceptions are meant to signify errors that could not be handled--unlike in Java, you shouldn't use exceptions for control flow.
The real issue is one of semantics--in Java, one concept (exceptions) is used to represent two do disparate things: signal unexpected errors (runtime exceptions) and manage expected conditions (checked exceptions). A lot of people do not like checked exceptions and think exceptions should only really be used for the former case. Thus the lack of checked exceptions is a feature rather than a bug; moreover, it is a feature other people in this thread have already requested.
So, the potentially annoying answer is that people using your library should not expect particular exceptions--that is not what they should be used for in Gosu. Coincidentally, this is very similar to how JavaScript deals with exceptions, and I have had no issues there at all.
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.
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);
[1]: https://wiki.php.net/rfc/functionarraydereferencing
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.
What I have a bigger problem with is the syntax for updating fields is so clumsy. It doesn't go very well with the rest of the language and I usually end up writing helper functions for updating specific combination of fields.
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. =]
var module = new Module();
In addition, AFAIK there are some funny issues in JavaScript when a constructor function returns an object that is not the object bound to `this` (i.e. the new object created by the `new` keyword).
There are still other problems (in my opinion) with the concept of constructor functions. It basically boils down to mixing data (prototype) and code (constructor funciton).
Side-effects in a constructor are a big no-no. However, if you want side-effects, you're forced to write your code in a different style.
As a (really bad) example, you have an Enemy "class" which must know about enemies adjacent to itself at creation time.
Without side-effects (using `new`):
With side-effects (using `new`): And without constructors, but with side-effects: The problem here is that an enemy must be part of a list. The classical OO solution is to use constructor parameters. Ideally, I'd just have a function to deal with creation and adding it to the list (like `createEnemy`).In ES5, `enemyList.createEnemy` could be written like this:
I'd much prefer something like: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).
So if a tree falls in the forest with no one around then the universe implodes.
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:
Whereas Tuple<> forces you to write that with ItemX scattered around.Tuples, on the other hand, are full-fledged generic classes. That introduces an advantage in that they're first-class entities which can be used anywhere. But it introduces a couple disadvantages, too: There's a separate class implementation for each number of elements, and implementations are only provided for up to 7 elements plus an 8th weird kludge for supporting more. And having the tuple's "official name" be Tuple<$ARBITRARY_LIST_OF_TYPES> is not only cumbersome, but also misses an opportunity to do a better job of communicating semantics.
Consider, for the sake of argument:
Tuple<Employee, int, string, double, string, bool>
versus
Tuple<Employee, int?, string, double, string, bool>
What's going on here? Are they equivalent? What are they being used for? What's up with the different types for Item2, are they equivalent? For that matter, what about Item3? Sure it's got the same type, but we've really got no idea what it's being used for. And since it's being implemented as a plain old generic class, there's no class definition on which you can lay some documentation about this stuff. Just a bunch of disembodied type declarations all more-or-less equivalent to each other.
You know that phase in a lot of beginning programmers' careers where every variable is named foo1, foo2, etc? This is in many ways the same thing, only codified and enshrined by the .NET Framework designers. Oh, and the word's "Item" instead of "foo".
Practically speaking, it means that Tuple's crippled. Sure, technically you can use it for anything. But if you're the kind of person who likes maintainable code, you really don't want to be using it for anything but the most trivial cases. You certainly shouldn't be using it in any interfaces that other people are going to have to work with.
Not a huge fan of C# but that part is awesome.
`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.
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.
I would like to see Lisp and *nix have babies. Take the best ideas of both and make something greater than their sum.
Are you referring to Unix tools (grep, awk, sed, cat, etc.), piping and redirection, or shell scripting overall?
GCC can do it, but it puts them on the stack which is limiting.
If you use Clang you can use them on non-Apple platforms.
Python: blocks, ala Ruby
JavaScript: Strong (but dynamic) typing, ala Python & Ruby
edit: formatting
Oh, also I'd make binding_of_caller work.
Edit: Never mind, I just tried it and got an error.
Weird. I could have sworn I'd seen it done somewhere.
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.
As an aside I just had a look at what stage Reia is up to. The github page says that Reia is now defunct. (https://github.com/tarcieri/reia)
There is also another ruby-like language on the erlang VM - Elixir (https://github.com/josevalim/elixir)
He's definitely familiar with Erlang as IIRC he was one of the original authors.
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.
SBCL: tree shaker for creating executables.