June 22, 2019
On Saturday, 22 June 2019 at 09:57:30 UTC, Mike Franklin wrote:
> I could get by with structs, basic types, functions, and typical flow-control features of any language.  I wouldn't enjoy it, though, for anything complex.

Yes, even though the goal is to find a minimal language subset, the resulting language shouldn't feel limiting.

So does this mean that things like lacking runtime-resolved virtual functions will feel limiting? Or would statically resolved virtual functions be enough, or is not having virtual functions ok if you have some other feature like interfaces?

> So the features I would prefer would probably depend greatly on the complexity of the project I was working on and the resource constraints of the platform.

Yes, available memory is also growing on embedded platform.


> That is why I think the opt-in continuum (https://forum.dlang.org/post/q7j4sl$17pe$1@digitalmars.com) that Andrei mentioned a while back is so important.  It allows one to scale up with the complexity of the project and/or the available resources of the platform.

Yes, I believe that also was the goal of Rust, to have close to no runtime library.

However I think one might distinguish between type-system-mechanisms and features that are necessary for code generation and those that are only for verification and testing.

For instance, I am not convinced that features that enable the Rust borrow checker has to be part of the language.  But I haven't given that a lot of thought.  It seems like it could be done with as library types, with annotations, and an external static analysis pass.

Similarily, there is no need for unittests to be a language feature in D. You can achieve the same with annotations and an external pass.

More importantly, if a language is kept minimal, with solid meta programming and annotation capabilities, then you can increase the opt-in-continuum by integrating external tooling.

June 22, 2019
On Saturday, 22 June 2019 at 10:22:10 UTC, Ola Fosheim Grøstad wrote:

> So does this mean that things like lacking runtime-resolved virtual functions will feel limiting? Or would statically resolved virtual functions be enough, or is not having virtual functions ok if you have some other feature like interfaces?

I think that's a good point. In the embedded systems that I've programmed, so much is known statically, at compile-time, so I just don't really have much need for many runtime features.  However, some embedded systems today are much more powerful than PC of the 1990's, and include 2D graphics and such.  I might prefer more runtime features in a scenario like that, but I think I could probably get by without them, especially since you other ways to dynamically dispatch.


> Yes, I believe that also was the goal of Rust, to have close to no runtime library.
>
> However I think one might distinguish between type-system-mechanisms and features that are necessary for code generation and those that are only for verification and testing.
>
> For instance, I am not convinced that features that enable the Rust borrow checker has to be part of the language.  But I haven't given that a lot of thought.  It seems like it could be done with as library types, with annotations, and an external static analysis pass.

I've been wondering about that too.  I think D's lifetime annotations (scope and return) get you pretty far, but D still allows two mutable references to one object.  It'd be nice to have some control over that in D.

> Similarily, there is no need for unittests to be a language feature in D. You can achieve the same with annotations and an external pass.

Agreed. It's mostly a convenience because it allows you to place the test locally next to the implementation.

> More importantly, if a language is kept minimal, with solid meta programming and annotation capabilities, then you can increase the opt-in-continuum by integrating external tooling.

Agreed, but I would prefer library features over tooling.

Mike
June 22, 2019
On Saturday, 22 June 2019 at 10:10:13 UTC, Mike Franklin wrote:
> Interfaces are an obvious one to me.  They can be implemented using D's introspection features, and in some cases they aren't even really necessary.  See this discussion on the topic:  https://forum.dlang.org/post/qndhfzrnipsnvsstrdvg@forum.dlang.org

Yes, static interfaces can be done by duck-typing and conventions.  Although it is difficult to ensure type safety with duck-typing alone (but one can improve on that with an enum that says something about capabilities and test those with a static assert).


> Classes are another.  See https://theartofmachinery.com/2018/08/13/inheritance_and_polymorphism_2.html for a very interesting implementation of class-like behavior without classes.  I think D may need additional features to make it work seamlessly without language support, but you can get pretty far today.

Hmm, yes, that wasn't very clean... I guess this is a good argument for providing AST manipulation features ("AST macros").


> I'm quite convinced that if we added `opImplicitCast` to the language, we could implement `alias this` and multiple `alias this` in the language.  There was a recent discussion about that too: https://forum.dlang.org/post/ozdjozskgwqxfykijrsh@forum.dlang.org

Hmm, yes, but if one is forced to resort to using string concatenation in a macroish fashion then I think that would be a sign of a missing language feature or that the meta programming capabilities need improvement.

Although, perhaps the argument you are making is that "alias this" is not really needed, but if you absolutely need it one time, then it is possible?  Like an "escape-hatch"?


> I have a few others, but I think those examples illustrate the general idea.  Basically, I'd double-down on the introspection, metaprogramming, and compile-time features of D, and then use those features to implement whatever features one needs.

Yes, that seems reasonable, as long as it doesn't harm the type system and the bugs that a strict type system can catch.

That is one of the issues that can arise with very generic template based code, that it can easily accept anything with no warning.


>  Some are concerned about falling for the Lisp curse (http://winestockwebdesign.com/Essays/Lisp_Curse.html), but I think it can be done tastefully to avoid that.

I don't really think this necessarily is an issue for embedded/low level systems programming if you have "LISP"-like coding features limited to libraries in the same way D now does with @safe.

I don't think low level programmers will absorb badly written libraries in the same way that people do in some high level contexts (javascript *coughs*).

June 22, 2019
On Saturday, 22 June 2019 at 10:50:35 UTC, Ola Fosheim Grøstad wrote:

>> I'm quite convinced that if we added `opImplicitCast` to the language, we could implement `alias this` and multiple `alias this` in the language.  There was a recent discussion about that too: https://forum.dlang.org/post/ozdjozskgwqxfykijrsh@forum.dlang.org
>
> Hmm, yes, but if one is forced to resort to using string concatenation in a macroish fashion then I think that would be a sign of a missing language feature or that the meta programming capabilities need improvement.

Yes, my implementation in that post was extremely poor, and that's being kind.  Adam's response was appropriate.  It was just an illustration, and I'm sure there are better ways to implement it, as Adam showed.  My point was that D has sufficient metaprogramming and introspection features to do it, and if it were implemented in the library it would be encapsulated from the user and would sit quietly in a dark corner of D's library.  Most people will just use it and never look at the implementation as long as it works.

> Although, perhaps the argument you are making is that "alias this" is not really needed, but if you absolutely need it one time, then it is possible?  Like an "escape-hatch"?

No, I would use it extensively to implement convenient composition and avoid inheritance.

Mike
June 22, 2019
On Saturday, 22 June 2019 at 10:22:10 UTC, Ola Fosheim Grøstad wrote:
>
> For instance, I am not convinced that features that enable the Rust borrow checker has to be part of the language.  But I haven't given that a lot of thought.  It seems like it could be done with as library types, with annotations, and an external static analysis pass.

https://dlang.org/phobos/std_typecons.html#Unique

> Similarily, there is no need for unittests to be a language feature in D. You can achieve the same with annotations and an external pass.

I honestly think unittest is the best idea ever...
___
I understand people frustrated with the GC, and in retrospect we all agree everything in the runtime should have been, or should be made, buy-in. But I don't understand the benefit of isolating out of the language and re-implement as libraries what is already isolated and buy-in in the language.

And if I wanted that, I wouldn't start by stripping down D. I'd start by extending C. We could call it C with Templates, later rename it to C<<>>... and ten years later we could be debating again improvement proposals to implement multiple inheritance. :p
June 22, 2019
On Saturday, 22 June 2019 at 10:50:35 UTC, Ola Fosheim Grøstad wrote:
>
> Yes, static interfaces can be done by duck-typing and conventions.  Although it is difficult to ensure type safety with duck-typing alone (but one can improve on that with an enum that says something about capabilities and test those with a static assert).

This sounds like the Erlang recommendation (they call it tagged tuples, records).

>
> Hmm, yes, that wasn't very clean... I guess this is a good argument for providing AST manipulation features ("AST macros").

Nim has AST macros.

> ...

June 22, 2019
On Saturday, 22 June 2019 at 12:27:32 UTC, XavierAP wrote:
> should be made, buy-in. But I don't understand the benefit of isolating out of the language and re-implement as libraries what is already isolated and buy-in in the language.

There are several benefits, one is that you can identify missing pieces in the metaprogramming feature set.

Another is that it becomes easier to reimplement the language and thus you can get better static analysis.

A third is that you can easier analyze the language if it is reduced to a minimal set, so you can better understand the effect of extending the language.

A fourth is that you with a minimal set get the opportunity to add AST-manipulation (AST macros).

A fifth is that if the optimizer can work with general implementation strategies rather than special cases then all code benefits from new optimization stages.

A sixth is that there is less code to maintain, so you can get better structure on the compiler code base.

Or you could just view it as a low-cost experiment.


> And if I wanted that, I wouldn't start by stripping down D. I'd start by extending C.

That would be a lot of work.

Besides the primary advantage of C is compatibility.

Compiling to C is worthwhile though, enables support for niche hardware platforms, SoC solutions etc (System on A Chip).

June 24, 2019
On Saturday, 22 June 2019 at 16:45:55 UTC, Yatheendra wrote:
> This sounds like the Erlang recommendation (they call it tagged tuples, records).

Sort of, except it is compile-time only.

> Nim has AST macros.

I have no real experience with Nim, but the AST macros seems to be very close to the parse-tree. I could be wrong, but I think something more abstract is needed.


June 24, 2019
On Saturday, 22 June 2019 at 06:55:40 UTC, Ola Fosheim Grøstad wrote:
> I am wondering, what would a minimal subset of D look like?  Something that would make the syntax/semantics look simple to a newbie wanting to do embedded programming, yet be useful.  Let's assume that we are already limited to the better-C subset.
>
> What are the "must have" features?  I assume that "static if" ranks high for most D users, but what else?

I'd assume a D successor would be JIT'ed with a big runtime, with types as firstt-class values, erasing the difference between compile-time and runtime.
In short, a bit like a typed LISP.
June 24, 2019
On Monday, 24 June 2019 at 10:31:27 UTC, Ola Fosheim Grøstad wrote:
> On Saturday, 22 June 2019 at 16:45:55 UTC, Yatheendra wrote:
>> This sounds like the Erlang recommendation (they call it tagged tuples, records).
>
> Sort of, except it is compile-time only.
>
>> Nim has AST macros.
>
> I have no real experience with Nim, but the AST macros seems to be very close to the parse-tree. I could be wrong, but I think something more abstract is needed.


**Disclaimer**: I invented Nim.

The AST is "close to" the parse-tree but that's not a problem, the usual things that a macro system is capable of can all be done (async, serialization, lazy evaluation, control flow abstractions, currying, DSLs), and reasonably easy too.

It's certainly ugly in some ways but that is not because it is "close to" the parse-tree (hey, it works for Lisp too!) but because it was a research project that escaped the lab. Almost no effort was spent on API design. But we're getting there.