DEV Community

Discussion on: If you could write a programming language how would it be?

Collapse
courier10pt profile image
Bob van Hoove • Edited on

I'm not a language expert. But I could think of a feature that would work in C# / Java. I really don't like DI boilerplate code. So rather than writing:

public class Composed
{
    private DepA a;
    private DepB b;
    private DepC c;
    private DepD d;
    private DepE e;

    // I usually move the constructor to the bottom since
    // taking dependencies is the least interesting thing
    // my class does

    public Composed(DepA a, DepB b, DepC c, DepD d, DepE e)
    {
        // hooray for throw expressions, saving us 5 boring LOC :)

        this.a = a ?? throw new ArgumentNullException(nameof(a));
        this.b = b ?? throw new ArgumentNullException(nameof(b));
        this.c = c ?? throw new ArgumentNullException(nameof(c));
        this.d = d ?? throw new ArgumentNullException(nameof(d));
        this.e = e ?? throw new ArgumentNullException(nameof(e));
    }
}

I'd like to write

public class Composed
{
    // Constructor is inferred
    private injected DepA a;
    private injected DepB b;
    private injected DepC c;
    private injected DepD d;
    private injected DepE e;

    //
    // Stuff that matters right at the beginning, no boilerplate
    //
}

I may be naïve though:

  • This implies that you cannot take 2 dependencies of the same type using the fictuous injected keyword. The new tuple features could be of help.
  • If you have 5 or more constructor arguments maybe it's time recompose.
  • Perhaps I should give F# a go?
  • Now you might need a method for other stuff you want to do during construction

EDIT: Extra con argument, spelling

Collapse
tobias_salzmann profile image
Tobias Salzmann

To me, it seems that what you really want is boilerplate free constructors. Even on the JVM, there are already some languages that do this quite well, Kotlin and Scala.

class Composed @injected() (
  private val a: DepA,
  private val b: DepB,
) {
 ...
}

You could make the injected annotation a keyword in your language. That way, you would still clearly communicate what a dependency is, and keep the class usable without dependency injection (in tests, for example)

Collapse
courier10pt profile image
Bob van Hoove

Boilerplate free it is :) Thanks for the example.

For professional purposes I'm going to stay with .Net for a while. I'm lucky to have enough interesting projects where the challenge is not so much tied to the language.

For trying something new Kotlin is indeed a great contender. I've watched KotlinConf 2017 - Introduction to Coroutines by Roman Elizarov just to get an idea and I was pretty impressed.

Collapse
eljayadobe profile image
Eljay-Adobe

I've heard good things about PostSharp, which provides exactly the kind of "get rid of the boring boilerplate" capability for C# that you want.

Not sure what is available for Java. My friends that are programming for JVM are pretty much using Kotlin, Scala, or Clojure these days. Clojure has all the meta-programming goodness you could possibly want, and it also emphasizes functional programming... and if you like Lisp you'll be right at home! (But if you don't like Lisp, you may grimace.)

Collapse
courier10pt profile image
Bob van Hoove

I have no allergy to parentheses, I've dealt with Lisp when in college and experienced no itch whatsoever :) I do sense that giving FP a try for real is only a matter time.

Collapse
tobias_salzmann profile image
Tobias Salzmann

Scala also has decent meta programming with scala.meta scalameta.org/.
There's also a high chance that as an API creator, you might get by using a library such as shapeless, to avoid manipulating the AST (yourself) completely github.com/milessabin/shapeless

I do love the fact that in clojure, meta programming is very similar to non-meta-programming.

Collapse
alainvanhout profile image
Alain Van Hout

In Java with Spring, you already get this via @Autowired/@Inject, though that's of course a framework-level rather than a language-level feature. (this mindset is a big reason why I favour field injection over constructor injection)

Collapse
courier10pt profile image
Bob van Hoove

I think this would be possible in .Net if you use attributes on the properties.

What I like about constructor injection is that the dependency requirement is by 'contract' regardless of how you compose. Even without a DI framework there's still only 1 way to compose the object.

I can see how field injection could be more practical. I should ask my Java colleagues about Dependency Injection in Spring :)

Thread Thread
alainvanhout profile image
Alain Van Hout • Edited on

Also in the Java world, people with strong views on DI tend to favour constructor injection, generally because it's more 'pure' (i.e. not bound to a DI framework and manually usable).

I see these kinds of fields as a special kind of field (similar to in your post) and as such see the use of the constructor as pointless boilerplate at best and a loss of pertinent semantics at worst).

Collapse
mortoray profile image
edA‑qa mort‑ora‑y

Ultimately all programmer's desire meta-programming capabilities. It's unfortunate that most new languages tend to rail against the idea (for example, when's the last time you've seen a Macro preprocessor since C/C++?)

I believe there is a draft for even more extended meta-programming for C++.

I hate redundancy, thus will be looking for all ways to get rid of it in Leaf. I like your example since it points out how meta-programming can be used to add clarity to your code. injected says a lot more about intent than does a constructor parameter.

Collapse
lucasfrota profile image
Lucas Frota Author

I really liked that idea, it looks much easier and simple, although I think it will require some organization from the programmers