My favorites | Sign in
Google
                
Search
for
Updated Sep 20, 2009 by aeagle22206
Features  
Planned or proposed language features

Fundamentals

Readability

Good stdlib

Injection

Immutability

Strong inferred typing

Exceptions

Class parameters and properties

Testing

Public API

Literals

Lots of useful literals!

Optional to separate bindings from code

Can we provide bindings to the injection framework inline, using scopes and @ImplementedBy and such? See PropositionForScopes.

Enforce naming conventions

This can help to improve readability, although we should take care to only enforce widely-agreed-upon conventions.


Comment by christianedwardgruber, Aug 15, 2009

Thoughts - I think we can avoid bindings where there are obvious singletons (or scopeltons, as I like to call 1-per-scope). Because the compiler/runtime can infer the type to be injected. However, there are problems when you get into the world of testing, or multiple implementations. Modules allow one to wire one way, or another in a different context, without burdening the interface and implementation(s) with pre-knowledge of how they will be bound. If we do that, we're not delegating wiring, and we miss the point. We would sacrifice re-use, etc. We do need a clean way of expressing it, but something has to replace modules, and it shouldn't be expressed with in any of the classes/interfaces to be bound.

Comment by aeagle22206, Aug 16, 2009

In the previous comment, I think you're objecting to something like @ImplementedBy?? I agree that we must be able to delegate the wiring, but can't this be treated as an overridable default?

As for checked vs. unchecked exceptions, I really don't like checked exceptions. I can go into it, unless there's already consensus :)

Comment by christianedwardgruber, Aug 18, 2009

I'm all for unchecked exceptions. And I am concerend with @ImplementedBy?. I can live with that as the default, but I'd rather have it not be there at all, as it creates knowledge by the interface of an implementation, and I think that's evil. That's the wrong direction for a dependency. Wrong wrong wrong. To me that's the job of the binder, if it find ambiguity. (I'm not even really happy with declaring scope on the interface or implementation, as it ties the use of the thing to its definition, when it could be used in different contexts. I'd rather declare that at binding time, and if there is no specific binding, it should either default to singleton, or default to "prototype" (instantiated once per request from the container)

Comment by gabrielh, Sep 07, 2009

How would we feel about "and" and "or" (python style) instead of && and || ?

For readability.

Comment by aeagle22206, Sep 08, 2009

I personally like "and" and "or".

I was thinking, part of readability is that even people who aren't very familiar with a language should be able to do code reviews at least - so the notion of readability should be as universal as possible. That's why leaving parentheses off method calls in Scala is trouble - if you don't know Scala, it's hard to read that a method is being called.

Following that logic, most coders will be used to reading "&&" and "||" from other languages they know, so not sure we can declare "and" and "or" to be more readable.

Comment by christianedwardgruber, Sep 08, 2009

I prefer it, but do we then have xor, nor, xnor, nand?

Comment by gabrielh, Sep 08, 2009

Yeah, perhaps.. I personally find it more readable and I think there is good precedence for it in python and ruby, but totally understand the other view... As far as xor, nand, etc, if we were to have "and" and "or" and if we aren't afraid to add keywords, why not? :)

if foo and bar:
if not foo:

On an sort of related note, I always liked being able to give the conditional at the end:

foo = 2 if bar; // Ruby style
foo = 2 if bar else 0; // Python style where else is required, which I find super annoying sometimes
bar = 1 unless foo; // Ruby style unless, though I find if not easier to deal with than unless in my brain
bar = 1 if not foo;

This gets to ternary expressions, which can be more readable this way as well...

foo = 1 if bar else 2;
foo = 2 unless bar else 1; // Probably unnecessary

Otherwise I guess we would use (a ? b : c) ?

Comment by robert.eaglestone, Sep 17, 2009

For most of the philosophy, fundamentals, readability, and API issues, wouldn't something akin to Smalltalk's grammar be one of the simplest and most powerful general solutions?

I know this is one of those horrid sniper's off-the-cuff comments, but I wonder if your energies are best focused on only fixing the broken wheels, rather than re-inventing all of them.

Comment by LuminariGWT, Sep 17, 2009

It would be nice if noop had some nice way to define templates for things like sql,html,xml,display layouts, which programmers are forced to use all the time. The vast majority of programming languages are pretty awful at making this code readable.

Comment by EvilGeenius, Sep 17, 2009

Where can i see some example code!!??

Comment by nihongo, Sep 17, 2009

not lexing the tab character only makes sense if whitespace is not whitespace, but syntactically meaningful, which it shouldn't be. If scoping is bracket-based (by using accolades) then the parser should be able to tokenise on /\s+/. Rejecting tabs due to a designers fondness of precise code indentation by using spaces would be baking personal preference where it has no business.

Comment by burton.miller, Sep 17, 2009

under Strong Inferred Types: Inferred types? foo = "bar" means foo is a String

please no - this harms readability - a LOT. instead, provide generic cast operation. this does not help the string case (which is not the problem), but helps in the much more common case of reduced readability through hard to read cast notation. sort of the other side of the coin.

SomeClass? bar; ... SomeOtherClass? foo := bar; // := means cast to my type or a superclass

or just do it on a regular assignment - assuming that casts are always happening when direct subtypes/interfaces do not match up.

the point is that the type for the destination should always be explicit, so you know what you end up with.

Comment by richard.roda, Sep 17, 2009

Please... please don't have checked exceptions. They are worse than useless. If you want to catch a specific exception with confidence in java, you have to have code that catches Exception and then unwraps it to find the specific exception it is looking for. This in essence reduces exceptions to an untyped system when looking for a specific exception type.

It results in implementation dependent brittle code. Look at the horror in java where methods and interfaces have to be either "remote" or "local" because remote methods have their exceptions wrapped in RemoteException?. Java reflection has similar exception wrapping issues. When you are compelled to reveal implementation details in an interface, something is wrong. Encapsulation 101 says the client should not know or care how the interface is implemented.

Exceptions by their very nature are implementation dependent. A throws clause should be nothing more than a documentation feature to inform calling code of exceptions that are thrown by the logical design. You don't want to have to wrap implementation specific exceptions. Either a method can handle an exception or it can't. If it can't, the exception should pass through to a higher layer. Any imposition of checked exceptions will result in the brittle implementation sensitive designs that are typical in Java.

Comment by johnzabroski, Sep 17, 2009

@Thoughts - I think we can avoid bindings where there are obvious singletons (or scopeltons, as I like to call 1-per-scope). Because the compiler/runtime can infer the type to be injected.

What? Singleton implementations are SUPPOSED to be dynamically substitutible. Just because most developers/designers don't do this, doesn't mean you should hardwire it as such. It's not just "scope". The implement class can be different, thanks to polymorphism. Am I missing your point?

Comment by john.lombardo, Sep 17, 2009

I like the gabrielh's vote to put the conditional at the end:

foo = 1 if bar;

I'd also like to suggest my favorite looping construct from Pick Basic (yes Basic):

loop {
   x = doSomething();
} while (!x) {
   doSomethingElse();
}

putting the test in the middle of the loop allows you to dispense with any setup code for the loop that has to be repeated within the loop -- it all goes before the test and will be executed again for each iteration.

Comment by avis.prede, Sep 17, 2009

I, for one, hate Python's triple-""" business, and far prefer a simple system of ".." only with \ attributed magic powers in the middle (so "\"", "\n", etc).

Also, where does that awful backtick for URIs come from, when there are existing uses of <> for the purpose?

Comment by cjdolan, Sep 17, 2009

For hash literals, what would be the hash type? <Object, Object>? Or would it be inferred from the tightest type that allowed all of the <keys, values>? Or would it be the types of the first key, value pair?

I'm guessing <Object, Object>.

Comment by m.a.navid, Sep 18, 2009

Please get rid of semicolons, they are the most useless piece in a programming language :(

Comment by ma...@mindcraftinc.com, Sep 18, 2009

An array is essentially a function that takes a numeric parameter and returns a value. A Map can also be viewed as a function that takes an object (usually a String) argument and returns an object. They are essentially parametrized objects. Why can't we unify the syntax?

A template (Generics) takes a parameter and behaves like a function also. Can we then move toward a syntax similar to the following?

Array(Int) factorial = {1, 1, 2, 6, 24, 120};
Int fourth = factorial(3); // fourth == 6
Object myObj = myMap("myKey");

We can standardize this feature for all classes by using a special method:

class TableRow() {
  String get(String name) { /* Return field name as a String */ }
  String get(Int    i   ) { /* Return field i    as a String */ }
}

TableRow row = getNextTableRow();
String city    = row(5);         // city == "Alexandria"
String country = row("Country"); // country == "Egypt"

This is especially useful if we can extend the syntax to set values and not only retrieve them. The syntax might then look like this:

class TableRow() {
  String get(Int i) {                 /* Return field i as a String */ }
  void   set(String value, Int key) { /* The  first parameter is the new value */ }
}

TableRow row = getNextTableRow();
String city = row(5);      // city == "Alexandria"
row(5)      = "Ankara";    // row(5) is mutable of course
String town = row(5);      // town == "Ankara"
Comment by axilmar, Sep 18, 2009

What you need is a strong dose of LISP. Forget dependency injection and such stuff. What you need is compile-time evaluation.

Comment by jeppe.b.smed, Sep 18, 2009

What is the background for omitting facilities for static code? I would love to see static fields go away, but static methods are mighty useful for setup/facade code. Why should it take object instantiation to do Integer.parseInt(..) ?

Comment by james.paul.white, Sep 18, 2009

While <uri> would be better than `uri`, I have to suppose it conflicts with the relational operators.

What would be even better is no literal markup at all. Have a scheme for registering protocol names (like SPARQL & Adenine @prefix) and then these are URI literals:

http://google.com/
urn:foo:xxx
dc:title
http://www.ifcx.org/wiki/Adenine.html

And +++1 for compile-time (and every other phase) evaluation.

Comment by robertsdionne, Sep 18, 2009

@jeppe.b.smed: It might not take object instantiation. I imagine we could create a standard facility for parsing Ints from Strings in an IntegerParser interface, which you would obtain like so:

class MyClass(IntegerParser parser, ...) {

  ...

  private void myHelperFunction() {
    String input = ...;

    // Do some work

    Int parsed = parser.parseInt(input);

    // Calculate something with parsed

    // Change internal state based on above calculation
  }
}

By default your injector could have a binding:

IntegerParser <- SystemIntegerParser

In your tests you could replace the binding with DumbIntegerParser? which simply returns 5 or some other suitable value.

Comment by diyisoft, Sep 18, 2009

well

Comment by soronthar, Sep 18, 2009

"Static methods" can go away if First Class Functions are added to the language. good or bad? I don't now.

Comment by spro...@videotron.ca, Sep 19, 2009

Checked exceptions are fine as long as they do not appear within the core language APIs. No checked SQL, IO, Security, etc. Checked exceptions are best used at the Domain level only. Allowing the language to document it's exceptions via a throws keyword is good.

Comment by healer.kx.yu, Sep 20, 2009

I do not like its name, why noop? no operation? And Scala and java, JRuby would take all the users~

Comment by teabot, Sep 21, 2009

How about making concurrency a first-class citizen? In our multi-core future we would all benefit from language constructs that make multi-threaded programming as simple as possible. Java 7's Fork/Join and util.concurrent are nice but it would be great to have some higher-level language constructs for concurrency.

Comment by lobais, Sep 21, 2009

I hope you are concidering the for...else construct, which is very useful when searching:

for item in list:
    if isWhatWeAreLookingFor(item):
        break 
else:
    print "item not fount"
Comment by pablogrisafi1975, Sep 22, 2009

One common mistake I happen to see a lot is equality check for floating point numbers, i.e

float a = 0.1f;
float b = 0;
for(int  i = 0; i < 10; i++){
    b += a;
    }
System.out.println(b == 1);

depending of float implementation, (b == 1) could be true or false. In java is indeed false, and this is counter intuitive for young programmers. I think simply don't allow equality checks for floating point or even including an equal-with-tolerance operator aprox(a, b, 0.001) in the language itself could be more than useful.

Comment by D.Bur...@esiee.fr, Sep 22, 2009
  • ++1 for not allowing floating point equality checks (except for 0.0 ?)
  • and why not consider an extended switch (without break) :
switch ( expression ) {
  case value1, value2 : { instructions }
  case value3, value4 : instruction;
  case value5 : { instructions }
  default : { instructions }
} // switch

checks if expression.equals(valueX) because everything is Object

specially useful with String :

switch( command.toLowerCase() ) {
  case "cp","copy" : { /* do the copy */ }
  case "mv","move" : { /* do the move */ }
  default : { System.out.println( "Unknown command : " + command ); }
} // switch
  • shouldn't we enforce the commented '}' ?

especially for classes, methods, and program structures (not for blocks); it greatly improves readability and debugging.

Comment by fetrovsky, Sep 22, 2009

Let's not ban float a, b; a==b... or double a, b; a==b... instead, let's make it easy to define what it means for the programmer: float.setEpsilon(1E-4); float a, b; floatsEqual = (a == b); double.setEpsilon(1E-10) double x, y; boolean doublesEqual = (x == y); also, please don't even consider multi-word types (e.g. long double, unsigned char).

Comment by fetrovsky, Sep 22, 2009

Also, along the lines of switch, as long as we're extending it, we can extend it even more:

switch (variable) { case 4, 5, 6, is > 1000, in someCollection: { someCollection.remove(variable); } case in someOtherCollection: { performOperation(variable, someOtherCollection); break;} default: { System.out.println("Don't know what to do with " + variable); } }

Comment by fetrovsky, Sep 22, 2009

That didn't get formatted right... trying again:

switch (variable) {
  case 4, 5, 6, is > 1000, in someCollection: {someCollection.remove(variable); }
  case in someOtherCollection: { performOperation(variable, someOtherCollection); break;}
  else: { System.out.println("Don't know what to do with " + variable); }
}

Please also note that I changed default: to else:.

Comment by bek...@web.de, Sep 27, 2009

Instead of

      for item in list:
          if isWhatWeAreLookingFor(item):
              break 
      else:
          print "item not fount"

I could simply write something like:

      var tmp = list.first(isWhatWeAreLookingFor);
      if (tmp == null)
         print("item not fount");

which is shorter, easier to read and more explicitly tells what you want (you want the first item that matches your criterion, not a bunch of implementation details).

Comment by oliver.doepner, Oct 06, 2009

Don't use "mutable", use "var" as the keyword for mutable references.

Comment by richfaber3, Oct 22, 2009

Why not get rid of Constructors named after the class... do it better like Ruby. Refactoring is simplified when the class just has "initialize"... Please at least allow it.