Skip to content
loading...
markdown guide
 

I’ve thought about this a lot, and writing a compiler is actually one of the projects on my GitHub but I’ve realized recently that my dream language is actually just JavaScript with 2 changes.

1) Module only operation, nothing in global scope except primitives (String, Number, Array, Symbol, Object), every other API must me called via import
2) and the addition of a ‘use native’; directive that could be used to make JS fully compliable within certain rules. Ie: forced jshint comments on all functions to define parameter types, no setting a variable to a type other than its initial, and no dynamic property setting unless in constructor

 

no setting a variable to a type other than its initial

+1 for type safe javascript w/o transpiling, I'd like that a lot

 

... no setting a variable to a type other than its initial ...

At a previous company, they developed a language called TypeScript that transpiles into JavaScript (ES3 or ES5). (Sorry Bob van Hoove... yep, transpiles.)

One of its features was static type checking, which went a long way to eliminate a large category of bugs. The folks at Google liked it so much, that they used it for Angular 2.

I worked on a very large project that used TypeScript throughout, and it was pretty nice. (TypeScript also made available a lot of ES6 features, way before ES6 was ready for primetime. So that was very cool too, at that time.)

Now we have ES6 at our disposal, so at least one big feature that TypeScript still provides is the static type checking.

Maybe some future version of JavaScript (ECMA-262 and ISO/IEC 16262) will add that into the core language.

 

TypeScript is very cool and I especially like their idea of automatic constructor property assignment but unfortunately, TS isn't supported natively and must be transpiled :(

 

You forgot 64bit integers and, perhaps, proper integers in general :-D

 

All numbers in JavaScript are automatically 64 bit floating-point numbers.
Source: ECMAScript 262 § The Number Type

Do you say that a 64-bit float-point number is as good as a 64-bit integer? stackoverflow.com/questions/964362...

No, in a perfect world, as a part of the 'use native' directive I mentioned in my OP comment, you would be able to comment on variables to specify the number type

something along the lines of

/** @type i64 */ // i64 could be replaced with any of i8,i16,i32,i64,f8,f16,f32,f64
const num = 12;
 

You like those scoping rules? You think hoisting is in any way sane?

 

Scoping and Hoisting are two very different things. No I don't particularly hoisting but the way module mode keeps the global scope almost entirely empty as well as the import/export system is wonderful for both library developers and site developers alike.

 

It'd be like this :)

The biggest challenge, besides actually writing a compiler, is sorting through the intense dogmas in the programming community and figuring out what features are really desired.

I'm taking the approach of top-level down: coming up with the code I want to see and then determining which features will make that happen. Of course, there's a lot of compromise, since a fully modern language takes a long time to develop, but needs a lot of people helping.

 

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

 

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.

 

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)

 

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.

 

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.)

 

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.

 

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.

 

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)

 

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 :)

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).

 

You should take a look at Kotlin, it might surprise you with this feature.

 

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

 

I've tried. It's hard.

Fortunately, there are several successful languages that I find to be outstanding.

  • D (v2.x), a better C++ than C++
  • Python (v3.x), everything — including the kitchen sink — scripting language
  • F# (v4.1), basically OCaml for .NET, which puts functional programming as the front-and-center foremost idiom
  • Lua (v5.x), powerful, lightweight, embeddable scripting language
 

I have also tried to create my own programming language but it is being much harder than I thought it would be, I mean it doesn't even work properly for now, here is the repository if if you're curious
github.com/Lucasfrota/lazy_cat_lang

Classic DEV Post from Aug 23 '19

Favorite Front-end/UI developer interview questions?

Help me compile your favorite interview questions.

Lucas Frota profile image