Re: Why can't we transpile C++ to D?

2021-06-10 Thread sighoya via Digitalmars-d-learn

On Thursday, 10 June 2021 at 15:09:02 UTC, Tejas wrote:
Sorry, I'm rather ignorant when it comes to this, but why can't 
we use [pegged](https://github.com/PhilippeSigaud/Pegged) to 
transpile C++ code to D?


See 
https://stackoverflow.com/questions/14589346/is-c-context-free-or-context-sensitive#answer-14589567


Mixing semantic with parsing isn't necessarily a good idea.

Then we won't need a nogc compatible std library and so many 
other things could get easier, like getting legacy code to use 
Dlang.


That doesn't solve the ABI compatibility to C++, only if source 
is available, but they may be compiled with compilers which can't 
build anymore with the current tool chain at least without to 
rebuild the tool chain.


It might not be worth it for C+17 and beyond, but older 
codebases could benefit significantly, right?


The problem is that old looking code doesn't become modern when 
it is transpired to D as the concepts to do things have changed.


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread sighoya via Digitalmars-d-learn

On Thursday, 27 May 2021 at 12:58:28 UTC, Christian Köstlin wrote:

That looks nice, but unfortunately my data for servers and 
users in the real world is not static but comes from a config 
file.


Okay, but then parametrizing the static lambda with runtime 
parameters should work. The important fact is that the closure 
needs to be static.


Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread sighoya via Digitalmars-d-learn

On Thursday, 27 May 2021 at 12:17:36 UTC, Christian Köstlin wrote:
Can you explain me, where here a double context is needed? 
Because all data now should be passed as arguments to amap?


Kind regards,
Christian


I  believe D's type system isn't smart enough to see independence 
between context and closure, otherwise your original example 
would also work as users and servers are context independent.


What about:

```D
string doSomething(string[] servers, string user) {
return user ~ servers[0];
}
void main() {
static servers = ["s1", "s2", "s3"];
static users = ["u1", "u2", "u3"];
static lambda = (string user) => servers.doSomething(user);
writeln(map!(user => servers.doSomething(user))(users));
writeln(taskPool.amap!(lambda)(users));
}
```



Re: How to work around the infamous dual-context when using delegates together with std.parallelism

2021-05-27 Thread sighoya via Digitalmars-d-learn

On Thursday, 27 May 2021 at 09:58:40 UTC, Christian Köstlin wrote:

I have this small program here

test.d:
```
import std;
string doSomething(string[] servers, string user) {
return user ~ servers[0];
}
void main() {
auto servers = ["s1", "s2", "s3"];
auto users = ["u1", "u2", "u3"];
writeln(map!(user => servers.doSomething(user))(users));
writeln(taskPool.amap!(user => 
servers.doSomething(user))(users));

}
```




I think it relates to 
https://issues.dlang.org/show_bug.cgi?id=5710


The reason is that amap requires a this pointer of type TaskPool 
and a context pointer to the closure which belongs to main, at 
least because it requires servers. Having both isn't possible due 
to problems in non DMD compilers.


If you rewrite it more statically:
```D
string doSomething(string[] servers, string user) {
return user ~ servers[0];
}

string closure(string user)
{
return servers.doSomething(user);
}
auto servers = ["s1", "s2", "s3"];
int main()
{
auto users = ["u1", "u2", "u3"];
writeln(map!(user => servers.doSomething(user))(users));
writeln(taskPool.amap!(closure)(users));
return 0;
}
```

PS: Just enable markdown if you want to highlight D code


Re: Why is this allowed? Inheritance variable shadowing

2021-05-26 Thread sighoya via Digitalmars-d-learn

On Wednesday, 26 May 2021 at 18:58:47 UTC, JN wrote:

I am not buying the "C++ does it and it's legal there" argument.


A point for it is the consistency with methods which also 
redefine super methods as default strategy.

The question is if the default strategy needs to be changed?
I wouldn't argue so as overriding super methods/fields as default 
is much more dangerous as it might destroy the super class's 
semantics.


What about explicitly tagging fields with override instead, then 
it would be a compile error if the base class hasn't the tagged 
fields.




Re: How does inheritance and vtables work wrt. C++ and interop with D? Fns w/ Multiple-inheritance args impossible to bind to?

2021-05-25 Thread sighoya via Digitalmars-d-learn

On Tuesday, 25 May 2021 at 02:47:19 UTC, Gavin Ray wrote:


The below seems to work at least, which is encouraging:


Awesome!
At least, it becomes problematic with fields in base classes, it 
would be nice if we could map them to @property annotated 
functions in D interfaces.


Re: How does inheritance and vtables work wrt. C++ and interop with D? Fns w/ Multiple-inheritance args impossible to bind to?

2021-05-24 Thread sighoya via Digitalmars-d-learn

On Monday, 24 May 2021 at 17:39:38 UTC, Gavin Ray wrote:

I'd be grateful for solid information on this


Here is a more informal report how it works in C++:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.23.4735=rep1=pdf

But in the end, I think a byte code analysis is needed to be 
sure. The best tools to visualize have already been proposed by 
you, so I think you are on a good path.


Re: How does inheritance and vtables work wrt. C++ and interop with D? Fns w/ Multiple-inheritance args impossible to bind to?

2021-05-24 Thread sighoya via Digitalmars-d-learn

On Monday, 24 May 2021 at 17:39:38 UTC, Gavin Ray wrote:
Hence why I was asking how to make D structs/classes that have 
compatible or identical vtables to multiply inherited objects 
to pass as arguments to `extern (C++)` functions.


I think classes annotated with extern is your only high level 
guaranteed == type safe option to be compatible to other c++ 
classes.


But you seek for the general multiple inheritance case which 
seems not to be supported with `extern`, sadly.
So you stick with manual solutions like template metaprogramming 
or/and raw pointer fiddling.
Anyway, both solutions would require an unsafe cast in the end, 
so you are on your own.






Re: ugly and/or useless features in the language.

2021-05-23 Thread sighoya via Digitalmars-d-learn

On Sunday, 23 May 2021 at 08:35:31 UTC, Tony wrote:
Why is metaprogramming added features better than the same 
features added in the language? One is standard between 
entities, the other is not.


Some points:
- Some features aren't general enough to be added as builtin but 
make sense to have them in libraries
- library features could be extended and modified arbitrarily 
which isn't possible with builtin features
- if better library features are found they can simply be removed 
from the library while probably breaking the library, it doesn't 
break the language which is much of a bigger problem
- most problems with builtin features is that they overwrite 
grammar for a certain scope a.k.a syntactic sugar leading to 
learn new rules/a new language (see C++) while a general 
framework would reuse the same grammar again and again providing 
uniformity
- most builtin features are added incrementally to a language in 
order to be predictable/implementable, unfortunately this leads 
often to fragmentation because later with enough practical 
experience you see another approach to solve the problem, making 
this approach available may overlap with the feature you already 
added, i.e. it solves to some extent the same problems but with 
other tradeoffs making it hard to choose the right approach.


There are also disadvantages, among them the locality/globaility 
problem: Implementing features via macros may need context 
information and other existing features need to be informed of 
the new feature in order to handle it correctly which would 
require many hooks which can't be solved solely with macros. We 
would require massive compiler reflection support for this. 
Further, it is unclear how it would behave at boundaries where 
hooks would collide with each other.





Re: ugly and/or useless features in the language.

2021-05-22 Thread sighoya via Digitalmars-d-learn
On Saturday, 22 May 2021 at 13:31:45 UTC, Ola Fosheim Grøstad 
wrote:

The D AST is not really suitable as it stands.


D is a bit like C++ in this regard, there might be a minimal 
core language that could be distilled from it, but it would take 
a D3 full breaking change to get there, so it won't happen.


Well, I think D without templates is already a lightweight core 
language. The real cost comes with the template language.


But I think providing an external ast tree mapped onto the 
changing internal one used by DMD would be a feasible approach.


Re: ugly and/or useless features in the language.

2021-05-22 Thread sighoya via Digitalmars-d-learn

On Saturday, 15 May 2021 at 14:31:08 UTC, Alain De Vos wrote:

Which parts in dlang don't you use and why ?


Well, I don't like magic constructs in the language like the type 
of AliasSeq you can't touch.


But the more general problem in D are not features per se, but 
how they are composed of.
For instance: Why no AST macros instead of string mixins, 
templates, mixin templates and alias?

All these forms could be special ast macros.

Structs are nice but at the same time awful to use because they 
are incompatible with interfaces and classes, I hope this will 
change to some extent, but I think it wouldn't be that smooth.


Being multi-paradigmatic seems nice at a first sight, but which 
paradigm should your standard library and other frameworks 
follow? Providing all paradigms at once make your frameworks 
redundant and bloated, so you just follow one which is most of 
the time not OOP.

This is the same problematic with custom memory containers.

I wish we would only use structs as ref/value types with the 
ability to box them to interfaces automatically increasing 
compatibility between libraries to a large extent.


Re: dlang vs crystal-language

2021-05-01 Thread sighoya via Digitalmars-d-learn

On Wednesday, 28 April 2021 at 22:41:03 UTC, Alain De Vos wrote:
What are the strengths and weaknesses comparing the two 
languages ?
I can name a strength of dlang is the working binding to tk and 
gtk.


Just to say, Crystal is a neat language, feels like a static ruby.

Strengths:

- Poweful type inference
- lightweight julian/ruby like syntax
- nice lightweight macros, don't know if they were a good fit for 
D

- nice yield builtins
- feels like a lightweight Java
- nice high level feeling and is GCed

Weaknesses:

- as I said, it is hard to understand when type inference is used 
completely everywhere, said that this is crystals killer feature
- slow compilation time just because of the "type inferred 
everywhere" design

- the OOP system lacks specific features from other OOP systems
- hasn't the same support for low level programming as in D or Nim
- is relative unknown, although I don't know why.


Re: write once type?

2021-04-30 Thread sighoya via Digitalmars-d-learn
On Friday, 30 April 2021 at 13:36:10 UTC, Steven Schveighoffer 
wrote:
I could have looped 2x over the args, and used an inner 
function to fetch the first one (or maybe used a staticIndexOf 
to get the first ColumnDef thing), and a second loop to verify 
all the remaining args have the same table def, but this loop 
works just as designed and is super-readable.


I would say likewise using static indexing, is it really that 
slow?


Otherwise, iterate over Pair-like partitions would also be a 
solution and compare if first.tableDef is second.tableDef, don't 
know if D has something for this statically available.


Further, I would like to refactor the static if out to an 
in-requirement, though I'm unsure if in-assertions support 
arbitrary exception types.




Re: dlang vs crystal-language

2021-04-30 Thread sighoya via Digitalmars-d-learn

On Thursday, 29 April 2021 at 22:47:08 UTC, Alain De Vos wrote:

What is the importance of type-annotations in which cases.


Specifying invariants which becomes very important when 
refactoring code.
Further it aids as documentation to understand the structures 
behind.



@X @Y @Z makes code sometimes unreadable.


You mean something like `List!(HashMap!(String,T))`, yes, but I 
like it in productive code.
It's often the case that verbosity becomes a plus in productive 
software development, as more people have to read code that to 
write it, a reason why Java is so successful



Sometimes there is a good reason


Mostly for prototyping and obvious cases. But the most important 
point of that is to write faster, I wish the IDE would help for 
this instead of the compiler's inference.


I even think D doesn't even profit very well for inferred types, 
you need anyway to specify auto which only saves work for large 
type(application)s.
But when they are large, you probably want to prefer annotating 
the type for the variable.


Instead, I want to point to some interesting solution C# offers 
to save typing and also being explicit about the type:

https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/#target-typed-new-expressions

In fact, one could imagine that they overload the new operator 
(at compiler level) to infer the type from the call site type 
annotation.




Re: write once type?

2021-04-30 Thread sighoya via Digitalmars-d-learn
On Friday, 30 April 2021 at 01:30:54 UTC, Steven Schveighoffer 
wrote:


In my case, for value of a certain type in the loop, I was 
storing a specific field from the first one I found, and then 
verifying that all the other values of that type (not exactly 
the same type, but similar) had the same value for that field, 
otherwise it was an error.


I could have done it in 2 loops, but it's wasteful.


I have problems to grok exactly what you're talking about, can 
you provide some neat and small example for this?





Re: write once type?

2021-04-29 Thread sighoya via Digitalmars-d-learn
On Tuesday, 20 April 2021 at 19:56:33 UTC, Steven Schveighoffer 
wrote:
Not only that, but I may also want to keep processing the loop 
and do something different if the value has already been set 
instead of returning immediately, which necessitates a second 
loop.


Can I ask why you require to handle it in one loop?
As I see it, you are required to poll over isSet/isNotSet in 
every iteration.




Re: dlang vs crystal-language

2021-04-29 Thread sighoya via Digitalmars-d-learn

On Wednesday, 28 April 2021 at 22:41:03 UTC, Alain De Vos wrote:
What are the strengths and weaknesses comparing the two 
languages ?
I can name a strength of dlang is the working binding to tk and 
gtk.


Less type annotations, fewer guarantees, less compile performance 
as cons.


Re: Why many programmers don't like GC?

2021-01-14 Thread sighoya via Digitalmars-d-learn
On Thursday, 14 January 2021 at 13:08:06 UTC, Ola Fosheim Grøstad 
wrote:


Because Java has a well defined virtual machine with lots of 
restrictions.


So you're insisting this isn't possible in D?


Re: Why many programmers don't like GC?

2021-01-14 Thread sighoya via Digitalmars-d-learn
On Thursday, 14 January 2021 at 11:11:58 UTC, Ola Fosheim Grøstad 
wrote:


I know your response is *tongue in cheek*, but I actually find 
it easier to use c++11 style memory management across the board 
than mixing two models.


But this is already the case for C++ and Rust. Remembering the 
days back developing in C++ there were a huge amount of memory 
deallocation side effects because opencv's memory management 
differs from qt's memory management.

Just to say it was a hell.

Personally, I find it better to prefer encapsulating manual 
memory management and not to leak them outside.


Re: Why many programmers don't like GC?

2021-01-14 Thread sighoya via Digitalmars-d-learn
As other people already mentioned, garbage collection incurs some 
amount of non-determinism and people working in low level areas 
prefer to handle things deterministically because they think 
non-deterministic handling of memory makes your code slow.


For example rendering in gaming gets paused by the GC prolonging 
the whole rendering process.
The conclusion arrives that code runs slow, but it doesn't. In 
fact, a tracing GC tries to do the opposite, in order to make the 
whole process faster, it releases memory in a buffer like mode 
often yielding faster execution in the long run, but not in the 
short run where it is mandatory not to introduce any kind of 
pauses.


So, in the end, it isn't a fate about performance rather a fate 
of determinism vs non-determinism.


Non-determinism has the potential to let the code run faster.
For instance, no one really uses the proposed threading model in 
Rust with owned values where one thread can only work mutably on 
an owned value because other threads wanting to mutate that value 
have to wait. This works by creating a deterministic order of 
thread execution where each thread can only work after the other 
thread releases its work.
This model gets often praised in Rust but the potential seems 
only a theoretical one.
As a result you most often see the use of atomic reference 
counting (ARC) cluttering in codebases in Rust.


The other point is the increased memory footprint because you 
have a runtime memory manager taking responsibility over 
(de)allocation which is impossible to have in some areas of 
limited memory systems.


However, why just provide a one size fits all solution when there 
are plenty of GC algorithms for different kinds of problem 
domains?

Why not offering more than one just as it is the case in Java?
The advantage hereby is to adapt the GC algorithm after the 
program was compiled, so you can reuse the same program with 
different GC algorithms.




Re: Why D functions paramter can not implicit infer type of Variant?

2021-01-13 Thread sighoya via Digitalmars-d-learn

On Wednesday, 13 January 2021 at 19:38:55 UTC, Paul Backus wrote:

That's what Variant is--a struct that models the universal 
supertype (sometimes called "Top" or "Any").


Ahh right. Good point, so it already fits.


Re: Why D functions paramter can not implicit infer type of Variant?

2021-01-13 Thread sighoya via Digitalmars-d-learn

On Wednesday, 13 January 2021 at 16:17:02 UTC, Marcone wrote:

import std;

void a(int b){
}

void main()
{
  Variant c = 10;
  a(c); // Error
}

Need more sugar.


Two problems:

1.) Variant is library defined, compared to the language level 
there isn't a default strategy to choose int32 here, it could be 
also, short, long, unsigned ... not to mention all the alias this 
types.
Though it may be possible to define a default strategy but part 
of the problem is how to tell D to init the type parameters 
appropriately.


2.) c is mutable, what is if you return c and assign other values 
of other types to it?
Determining all possibilities by traversing following assignments 
leads to global type inference which no one would ever want to 
have especially with support of subtyping.


A more natural conclusion would be to infer c to the most common 
supertype as other inferences would unnecessarily exclude future 
assignments to c.  But the most common supertype doesn't seem to 
exist, and I'm unsure if this type can be modeled at all in D?





Re: I want to create my own Tuple type

2021-01-12 Thread sighoya via Digitalmars-d-learn

What about this?
No magic, but I don't know the performance impact.

```
import std.meta;
import std.conv;

template same(Types...)
{
static if (Types.length >= 2)
{
static if (is(Types[0] == Types[$ - 1]))
{
const same = same!(Types[1 .. $]);
}
else
{
enum bool same = false;
}
}
else
{
enum bool same = true;
}
}

struct Tuple(Types...)
{

static if (same!Types)
{
public Types[0][Types.length] elements;
public this(Types[0][Types.length] elements...)
{
this.elements = elements;
}
}

else
{
static foreach (int i, T; Types)
{
mixin("public " ~ T.stringof ~ " " ~ "elem" ~ 
i.stringof ~ ";");

}
public this(Types elements)
{
static foreach (int i, T; Types)
{
mixin("this.elem" ~ i.stringof ~ "=" ~ 
"elements[i]" ~ ";");

}
}
}
}

int main()
{
import std.stdio;

auto homogenousTuple = Tuple!(int, int)(2, 3);
writeln("homogenous tuple ", homogenousTuple.elements[0], ":",
typeid(homogenousTuple.elements[0]), ":", 
homogenousTuple.elements[1],

":", typeid(homogenousTuple.elements[1]));
auto heterogenousTuple = Tuple!(int, float)(2, 3);
writeln("heterogenous tuple ", heterogenousTuple.elem0, ":", 
typeid(heterogenousTuple.elem0),
":", heterogenousTuple.elem1, ":", 
typeid(heterogenousTuple.elem1));

return 0;
}
```

Problem is, the type arguments getn't inferred.


Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-10 Thread sighoya via Digitalmars-d-learn

On Saturday, 9 January 2021 at 18:16:04 UTC, Q. Schroll wrote:
This makes no sense in my head. Is there some reason I'm unable 
to see?


And yes, I think it should work likewise for function pointers, 
too.




Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-10 Thread sighoya via Digitalmars-d-learn

On Sunday, 10 January 2021 at 00:44:26 UTC, Q. Schroll wrote:



  Car[] cars = ...;
  Vehicle[] vehicles = cars;
  vehicles[0] = new Boat; // err...
  // cars[0] is a Boat now!?

Now what? Do what Java does and throw an Exception? Or use 
const to prevent mutation?


Yes, you are right:

```
Derived derived;
Base* bp=
*bp=base;
derived.method() //ouch
```


I'm unsure what you mean.


I mean D doesn't support co(ntra)varaince out of the box, but 
seems allowing them in certain cases increasing the degree of 
confusion just as it is the case here.
I think it would be just better to generally incorporate 
co(ntra)variance into D's semantic or completely disregard it.






Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread sighoya via Digitalmars-d-learn

On Saturday, 9 January 2021 at 20:20:38 UTC, Q. Schroll wrote:
That's not what I mean. You copy the reference. That's not what 
referencing meant.


  Derived d = new Derived();
  Base* bp =  // fails
  const(Base) cbp =  // compiles.


Generally, allowing covariant assignment for the Ptr, i.e. T*, 
type only in case of const T* strikes me. IMHO, both should be 
synchronously (dis)allowed.
Because D doesn't support co(ntra)variance, it should be both 
disallowed?
Otherwise, because D already support the const case, why not the 
non const case?


Are there any alignment issues supporting the non const case?


Re: DConf talk : Exceptions will disappear in the future?

2021-01-07 Thread sighoya via Digitalmars-d-learn

On Thursday, 7 January 2021 at 19:35:00 UTC, H. S. Teoh wrote:

Whether or not something is inlined has nothing to do with what 
line number it was written in.


Okay, I've tried it out, and it seems it isn't the problem in the 
binary case as the code was first compiled and the inlined, so 
the line number is correct in that case.


For source code inlining however, the direction is simply 
opposite. Therefore, compilation of inlined code have to respect 
the original line number pointing to the throw statement in the 
inlined function.


I think D can handle this, I hope so.


"Debugging information" can be included in production code.


Yes, but exception line numbers aren't debug infos rather they 
are passed implicitly as argument to the exception class 
constructor.


Re: DConf talk : Exceptions will disappear in the future?

2021-01-07 Thread sighoya via Digitalmars-d-learn

On Thursday, 7 January 2021 at 18:12:18 UTC, H. S. Teoh wrote:
If you're unfamiliar with the subject, I recommend reading a 
textbook on compiler construction.


I already read one.


Because every introduced catch block in the libunwind 
implementation introduces additional overhead.


But only when an exception is thrown, right?

Wrong. Out of memory only occurs at specific points in the code 
(i.e., when you call a memory allocation primitive).


What about pushing a new stack frame on top/bottom of the stack? 
This is very implicit. I don't talk about a theoretical Turing 
machine with unbounded memory, rather about a linear bounded 
automaton with finite memory.

What happens if stack memory isn't available anymore?

As I said, I don't know how this is handled in D, but in 
theory you can even inline an already compiled function though 
you need meta information to do that.


This tells me that you do not understand how compiled languages 
work.


Traditionally, inlining means the insertion of code from the 
callee into the caller, yes.
Imagine now, that the source code of the callee isn't available 
because it is already compiled and wrapped in a dynlib/static lib 
before (and now you link to that dynlib/static lib), then you 
can't inline the source code, but you can inline the binary code 
of the callee. For this to be "optimize-safe" regarding 
exceptions you need to store some meta information, e.g. the line 
number of all direct thrown exceptions in it, during the 
compilation of the callee in the dynlib/static lib for any caller 
outside the dynlib/static lib.
Theoretically, you can even pass functions as binary code blocks 
to the callee, this is mostly inperformant, but it is at least 
possible.


Though, I assume that most compiles doesn't any sort of this, but 
it doesn't mean that it isn't possible.


Again, I recommend reading a textbook on compiler construction. 
It will help you understand this issues better. (And it will 
also indirectly help you write better code, once you understand 
what exactly the compiler does with it, and what the machine 
actually does.)


It also depends on the considered compiler and how it is relating 
to the design discussed in textbooks.



All of this information is already available at compile-time. 
The compiler can be easily emit code to write this information 
into some error-handling area that can be looked up by the 
catch block.


Yes, but the line number is changing when inlining the code, and 
we don't want the new line number to be outputed by the runtime 
if an exception was thrown because it points to a line number 
only visible to the optimizer not to the user?


Also, you are confusing debugging information with the 
mechanism of try/catch.


So you only want to output line numbers in stack trace during 
debugging and not in production code?





Re: DConf talk : Exceptions will disappear in the future?

2021-01-07 Thread sighoya via Digitalmars-d-learn

On Thursday, 7 January 2021 at 14:34:50 UTC, H. S. Teoh wrote:
This has nothing to do with inlining.  Inlining is done at 
compile-time, and the inlined function becomes part of the 
caller.


True


There is no stack pointer decrementing involved anymore


Also true.


because there's no longer a function call in the emitted code.


And this is the problem, how to refer to the original line of the 
inlined function were the exception was thrown?
We need either some machinery for that to be backpropagated or we 
didn't inline at all in the said case.


One very important assumption is control flow: if you have 
operations A, B, C in your function and the optimizer can 
assume that control will always reach all 3 operations, then it 
can reorder the operations (e.g., to improve instruction cache 
coherence) without changing the meaning of the code.


Wonderful, we have an example!
If all three operations don't refer to depend on each other. Or 
maybe the compiler execute them in parallel. Did we refer to lazy 
evaluation or asynchronous code execution here?


If the exception were propagated via normal return mechanisms, 
then the optimizer still has a way to optimize it: it can do A 
and C first, then if B fails it can insert code to undo C, 
which may still be faster than doing A and C separately.


Puh, that's sounds a bit of reordering nondeterministic effectful 
operations which definitely aren't rollbackable in general, only 
in simple cases.
But in general, why not generate a try catch mechanism at compile 
time catching the exception in case B throws and store it 
temporarily in an exception variable.


After A has executed and was successful, just rethrow the 
exception of B.
All this could be generated at compile time, no runtime cost but 
involves some kind of code duplication.


This is why performance-conscious people prefer nothrow where 
possible: it lets the optimizer make more assumptions, and 
thereby, opens the possibility for better optimizations.


But the assumption is wrong, every function can fail, e.g. out of 
memory, aborting the whole program in this case just to do better 
optimizations isn't the fine english way.



This makes no sense. Inlining is done at compile-time; if you 
are loading the code as a dynamic library, by definition you're 
not inlining anymore.


As I said, I don't know how this is handled in D, but in theory 
you can even inline an already compiled function though you need 
meta information to do that. My idea was just to fetch the line 
number from the metadata of the throw statement in the callee in 
order to localize the error correctly in the original source code.





Re: DConf talk : Exceptions will disappear in the future?

2021-01-07 Thread sighoya via Digitalmars-d-learn

On Thursday, 7 January 2021 at 10:36:39 UTC, Jacob Carlborg wrote:

Swift can throw anything that implements the Error protocol. 
Classes, structs and enums can implement protocols.




True, Swift can throw anything what implements the Error 
protocol. It seems the error protocol itself doesn't define any 
constraints how an error has to look like.


I'm contemplating if this is a good idea, maybe, I don't know yet.

Some platforms implement C++ exception using longjmp, for 
example, iOS.


Interesting, I've heard some OSes don't support exception tables, 
therefore an alternate implementation have to be chosen.


It's claimed that exceptions are not zero cost, even when an 
exception is not thrown. Because the compiler cannot optimize 
functions that may throw as well as those that cannot throw.


Did you refer to the case a pure function is inlined into the 
caller and the machinery of stack pointer decrementation doesn't 
work anymore?


You may be right about that. However, I think it can be 
transformed safely in case the source code is still available.


In case of dyn libs, we may, can develop a machinery to gather 
exception table information at compile time and to manipulate 
them in order to inline them safely, but I don't know about the 
case in D though.


Re: DConf talk : Exceptions will disappear in the future?

2021-01-06 Thread sighoya via Digitalmars-d-learn

On Wednesday, 6 January 2021 at 21:27:59 UTC, H. S. Teoh wrote:
It must be unique because different functions may return 
different sets of error codes. If these sets overlap, then once 
the error propagates up the call stack it becomes ambiguous 
which error it is.


Contrived example:

enum FuncAError { fileNotFound = 1, ioError = 2 }
enum FuncBError { outOfMem = 1, networkError = 2 }

int funcA() { throw FuncAError.fileNotFound; }
int funcB() { throw FuncBError.outOfMem; }

void main() {
try {
funcA();
funcB();
} catch (Error e) {
// cannot distinguish between FuncAError and
// FuncBError
}
}



Thanks, reminds on swift error types which are enum cases.
So the type is the pointer to the enum or something which 
describes the enum uniquely and the context is the enum value, or 
does the context describe where to find the enum value in the 
statically allocated object.



Using the typeid is no good because: (1) typeid in D is a


Sorry, I misspelled it, I meant the internal id in which type is 
turned to by the compiler, not the RTTI structure of a type at 
runtime.


If you're in @nogc code, you can point to a 
statically-allocated block that the throwing code updates with 
relevant information about the error, e.g., a struct that 
contains further details about the error


But the amount of information for an error can't be statically 
known. So we can't pre-allocate it via a statically allocated 
block, we need some kind of runtime polymorphism here to know all 
the fields considered.


You don't need to box anything.  The unique type ID already 
tells you what type the context is, whether it's integer or 
pointer and what the type of the latter is.


The question is how can a type id as integer value do that, is 
there any mask to retrieve this kind of information from the type 
id field, e.g. the first three bits say something about the 
context data type or did we use some kind of log2n hashing of the 
typeid to retrieve that kind of information.



When you `throw` something, this is what is returned from the 
function. To propagate it, you just return it, using the usual 
function return mechanisms.  It's "zero-cost" because it the 
cost is exactly the same as normal returns from a function.


Except that bit check after each call is required which is 
neglectable for some function calls, but it's summing up rapidly 
for the whole amount of modularization.
Further, the space for the return value in the caller needs to be 
widened in some cases.


Only if you want to use traditional dynamically-allocated 
exceptions. If you only need error codes, no polymorphism is 
needed.


Checking the bit flag is runtime polymorphism, checking the type 
field against the catches is runtime polymorphism, checking what 
the typeid tells about the context type is runtime polymorphism. 
Checking the type of information behind the context pointer in 
case of non error codes is runtime polymorphism.
The only difference is it is coded somewhat more low level and is 
a bit more compact than a class object.
What if we use structs for exceptions where the first field is 
the type and the second field the string message pointer/or error 
code?



The traditional implementation of stack unwinding bypasses 
normal function return mechanisms.  It's basically a glorified 
longjmp() to the catch block, augmented with the automatic 
destruction of any objects that might need destruction on the 
way up the call stack.


It depends. There are two ways I know, either jumping or 
decrementing the stack pointer and read out the information in 
the exception tables.




Turns out, the latter is not quite so simple in practice.  In 
order to properly destroy objects on the way up to the catch 
block, you need to store information about what to destroy 
somewhere.


I can't imagine why this is different in your case, this is 
generally the problem of exception handling independent of the 
underlying mechanism. Once the pointer of the first landing pad 
is known, the control flow continues as known before until the 
next error is thrown.
You also need to know where the catch blocks are so that you 
know where to land. Once you land, you need to know how to 
match the exception type to what the catch block expects, etc.. 
To implement this, every function needs to setup standard stack 
frames so that libunwind knows how to unwind the stack.


Touché, that's better in case of error returns.

It also requires exception tables, an LSDA (language-specific 
data area) for each function, personality functions, etc..  A 
whole bunch of heavy machinery just to get things to work 
properly.



Why would you want to insert it into a list?  The context field 
is a type-erased pointer-sized value. It may not even be a 
pointer.




Good point, I don't know 

Re: DConf talk : Exceptions will disappear in the future?

2021-01-06 Thread sighoya via Digitalmars-d-learn

Citing Herb Sutter:
As noted in §1.1, preconditions, postconditions, and assertions 
are for identifying program bugs, they are never recoverable 
errors; violating them is always corruption, undefined behavior. 
Therefore they should never be reported via error reporting 
channels (regardless of whether exceptions, error codes, or 
another style is used). Instead, once we have contracts 
(expected in C++20), users should be taught to prefer expressing 
these as contracts, and we should consider using those also in 
the standard library.


Oh men, did you ever hear of non-determinism?
Why not just use compile time contracts and path dependent typing 
to solve those problems as well?

Because perfectionism is our enemy in productive development.
And terminating the whole program doesn't help either, exactly 
for this purpose we have error types or contexts, to know to 
which degree we are required to terminate and this should hold 
even for contracts.


Re: DConf talk : Exceptions will disappear in the future?

2021-01-06 Thread sighoya via Digitalmars-d-learn

On Tuesday, 5 January 2021 at 21:46:46 UTC, H. S. Teoh wrote:
4) The universal error type contains two fields: a type field 
and a context field.


a) The type field is an ID unique to every thrown exception 
--
uniqueness can be guaranteed by making this a pointer to 
some static

global object that the compiler implicitly inserts per throw
statement, so it will be unique even across shared 
libraries. The
catch block can use this field to determine what the error 
was, or
it can just call some standard function to turn this into a 
string

message, print it and abort.


Why it must be unique? Doesn't it suffice to return the typeid 
here?




b) The context field contains exception-specific data that 
gives
more information about the nature of the specific instance 
of the
error that occurred, e.g., an integer value, or a pointer 
to a
string description or block of additional information about 
the

error (set by the thrower), or even a pointer to a
dynamically-allocated exception object if the user wishes 
to use

traditional polymorphic exceptions.


Okay, but in 99% you need dynamically allocated objects because 
the context is most of the time simply unknown.


But yes, in specific cases a simple error code suffice, but even 
then it would be better to be aware that an error code is 
returned instead of a runtime object. It sucks to me to box over 
the context pointer/value to find out if it is an error code or 
not when I only want an error code.


c) The universal error type is constrained to have trivial 
move
semantics, i.e., propagating it up the call stack is as 
simple as
blitting the bytes over. (Any object(s) it points to need 
not be

thus constrained, though.)

The value semantics of the universal error type ensures that 
there is no overhead in propagating it up the call stack.  The 
universality of the universal error type allows it to represent 
errors of any kind without needing runtime polymorphism, thus 
eliminating the overhead the current exception implementation 
incurs.


So it seems the universal error type just tells me if there is or 
isn't error and checking for it is just a bitflip?


The context field, however, still allows runtime polymorphism 
to be supported, should the user wish to.


Which in most of the cases will be required.

The addition of the universal error type to return value is 
automated by the compiler, and the user need not worry about 
it.  The usual try/catch syntax can be built on top of it.


Of course, this was proposed for C++, so a D implementation 
will probably be somewhat different.  But the underlying thrust 
is: exceptions become value types by default, thus eliminating 
most of the overhead associated with the current exception 
implementation.


I didn't know exactly how this is implemented in D, but class 
objects are passed as simple pointer and pointers are likewise 
value types.
Using value types itself doesn't guarantee anything about 
performance, because the context field of an exception can be 
anything you need some kind of boxing involving runtime 
polymorphism anyway.


 Stack unwinding is replaced by normal function return 
mechanisms, which is much more optimizer-friendly.


I heard that all the time, but why is that true?


This also lets us support exceptions in @nogc code.


Okay, this would be optionally great. However, if we insert the 
context pointer into a List we may get a problem of cyclicity.


There is no need for a cascade of updates if you do it right. 
As I hinted at above, this enumeration does not have to be a 
literal enumeration from 0 to N; the only thing required is 
that it is unique *within the context of a running program*.  A 
pointer to a static global suffices to serve such a role: it is 
guaranteed to be unique in the program's address space, and it 
fits in a size_t.  The actual value may differ across different 
executions, but that's not a problem: any references to the ID 
from user code is resolved by the runtime dynamic linker -- as 
it already does for pointers to global objects.  This also 
takes care of any shared libraries or dynamically loaded .so's 
or DLLs.


What means unique, why is it important? Type ids aren't unique to 
distinguish exceptions and I don't know why we need this 
requirement.
The point in Rust or Java was to limit the plurality of error 
types a function call receive, but this is exactly the point 
where idiomatic and productive development differs. Assumptions 
change and there you are.



I've said this before, that the complaints about the current 
exception handling mechanism is really an issue of how it's 
implemented, rather than the concept of exceptions itself.


Okay, I think this is definitely debatable.

 If we implement Sutter's proposal, or something similar 
suitably adapted to D, it would eliminate the runtime overhead, 
solve the @nogc exceptions issue, and still support 

Re: DConf talk : Exceptions will disappear in the future?

2021-01-05 Thread sighoya via Digitalmars-d-learn
Personally, I don't appreciate error handling models much which 
pollute the return type of each function simply because of the 
conclusion that every function you define have to handle errors 
as errors can happen everywhere even in pure functions.


You don't believe me? What about memory overflow errors which can 
occur in any stack/heap allocation? Don't know how this is 
handled in D but in Java you got exceptions for this as well.


The other point is the direction which is chosen in Go and Rust 
to make error handling as deterministic as possible by 
enumerating all possible error types.
Afaict, this isn't a good idea as this increases the fragile code 
problem by over specifying behavior. Any change requires a 
cascade of updates if this is possible at all.

What you do in Rust then?, simply panic?
Though, it doesn't mean that it is bad in every case.

By churning different language design forums it all comes down to 
the point, every time, that the default error handling model 
equipped with the considered language is dump and that people 
call for extensions from other languages, even ones which include 
exception handling to improve things.


I see this in Rust and Go and even in Swift forums that people 
are annoyed how it currently works.


No error handling model was the HIT and will never be, therefore 
I would recommend to leave things as they are and to develop 
alternatives and not to replace existing ones.


Re: Recursively defined matcher function

2021-01-03 Thread sighoya via Digitalmars-d-learn

On Sunday, 3 January 2021 at 18:55:58 UTC, sighoya wrote:

```
alias matcherSignature(T:matcherSignature!T) = Matcher (T[]  
matchers...);

```


Yet, it is right:

```
alias matcherSignature(T:matcherSignature!T) = Matcher 
function(T[]  matchers...);

```

But it didn't work likewise, you have to instantiate it 
infinitely in nesting order.


I think you either need some kind of nominalism to state 
matcherSignature!T exists for any T or you need to end it after a 
certain depth:


```
struct theEnd {}

template matcherSignature(T) if (T==matcherSignature!T || 
T==theEnd)

{
Matcher function(T[] matchers...) fp;
}
```



Re: Recursively defined matcher function

2021-01-03 Thread sighoya via Digitalmars-d-learn

On Sunday, 3 January 2021 at 18:49:40 UTC, sighoya wrote:

```
alias matcherSignature(T:matcherSignature!T) = T (T[] 
matchers...);

```



Ahhh, I meant this:

```
alias matcherSignature(T:matcherSignature!T) = Matcher (T[]  
matchers...);

``

I think we would require proper singleton types to model this 
as:


```
matcherSignature(matcherSignature.type[] matcherSignatures ...)
```


and this:

```
Matcher matcherSignature(matcherSignature.type[] 
matcherSignatures...)

```


Re: Recursively defined matcher function

2021-01-03 Thread sighoya via Digitalmars-d-learn

On Sunday, 3 January 2021 at 18:26:44 UTC, Per Nordlöw wrote:

I've tried

alias Matcher = Match function(Matcher[] matchers...);

but it errors as

recursive alias declaration


The closest thing can I think of is:
```
alias matcherSignature(T:matcherSignature!T) = T (T[] 
matchers...);

```

I think we would require proper singleton types to model this as:

```
matcherSignature(matcherSignature.type[] matcherSignatures ...)
```


Re: C++ or D?

2020-12-30 Thread sighoya via Digitalmars-d-learn
On Wednesday, 30 December 2020 at 21:12:43 UTC, Ola Fosheim 
Grøstad wrote:

(which does not work, but maybe there is some other
way to express it?):


See: 
https://forum.dlang.org/thread/ooxzbrmbrzpsefiro...@forum.dlang.org?page=1




Re: C++ or D?

2020-12-30 Thread sighoya via Digitalmars-d-learn
On Wednesday, 30 December 2020 at 18:45:03 UTC, Ola Fosheim 
Grøstad wrote:
Some people in the D community has for a long time wanted 
stack-less coroutines. This is now available in C++20, and 
maybe D can borrow the C++ implementation for LDC? That is an 
interesting possibility for sure.




Hmm, I don't know much about them, but it seems they are a 
restriction to stackful coroutines, maybe a keyword addition like 
@stackless to prohibit nested suspension does the trick?


The main addition for C++20 is concepts. Basically wrapping up 
ugly tests in a simple template parameter type specifier so 
that you can specify that a template parameter MUST support 
Addition or be a Stack or whatever you want to require with 
very simple syntax. (It also makes it easier to specify tests.)


In my eyes, adding proper support for opImplicitCoercion enables 
the reuse of interfaces as typeclasses, yielding more potential 
for idiomatic development than utilizing C++ concepts alone.


Btw, did D ever get to add nested template parameters? I know 
people asked for it a long time ago, but cannot remember if 
that was resolved somehow?


Oh, what's this? Did you mean true Higher Kinded Types (HKT)

```
fun(R,S,T:R=>S)
```

That would be great, but they're simply arguing to use alias 
symbols instead. The downside with aliases is however a more 
restricted type inference:


https://github.com/dlang/DIPs/blob/bf5157d3dc29a591826e22d188448fbc04ca81b2/DIPs/DIP1023.md
https://forum.dlang.org/thread/dnyqxmgdazczwmmva...@forum.dlang.org?page=4


I almost never use multiple inheritance myself, but if you 
don't use it, it does not affect you at all? So how could it be 
a problem to have the option? *shrugs*


It's right, at least theoretically, practically you are often 
forced to use the feature in order to utilize the functionality 
you need.


But the more general point against this was the clash of fields 
and methods. However, this is akin to the problem with generic 
specialization, and likewise it can be solved by simply defining 
a new default instance, that's it.







Re: C++ or D?

2020-12-30 Thread sighoya via Digitalmars-d-learn
On Wednesday, 30 December 2020 at 14:41:28 UTC, Ola Fosheim 
Grøstad wrote:

Most of the statements are wrong too...
"4732 features, but not a single one you actually want": wrong 
again, C++20 has features that people would like to see in D



Could you elaborate a bit more, please? I'm interested.

"unsatisfying standard library": not really, unless you need to 
avoid exceptions


"template metaprogramming only capable of being understood by 
mensa member": some aspects of C++20 metaprogramming is easier 
than D



That would me interest, too!

"multiple-inheritance hell": no idea what this means, MI is 
usually used for the same as D interfaces


Just to say, I think not including multiple inheritance was a 
mistake for Java and all its descendants, though not a big one.


Multiple inheritance needs just a good convention, that's all.


Re: How to reliably detect an alias sequence?

2020-12-27 Thread sighoya via Digitalmars-d-learn

On Sunday, 27 December 2020 at 12:23:26 UTC, Max Samukha wrote:
Given a name bound to an alias sequence, what is a reliable way 
to detect that?


import std.meta: AliasSeq;

alias a = AliasSeq!int;

static if () {

}

__traits(isSame, a, AliasSeq!a) could work but doesn't, because 
it flattens singletons, which means __traits(isSame, int, 
AliasSeq!int) is true. (A bug/bad design, IMO. If the intended 
behavior is not to flatten tuples passed to __traits, there is 
no reason to make a special case for singletons).


This should work:
```
static assert(is(int == AliasSeq!int));
Drepl: static assert:  `is(int == (int))` is false
```

The most appropriate solution would be:
```
AliasSeq!int.stringof == (int);
```

But it wouldn't exclude false positives.


Re: Get the code of any D-entity as string?

2020-12-27 Thread sighoya via Digitalmars-d-learn

On Sunday, 27 December 2020 at 14:40:01 UTC, Basile B. wrote:


A more concrete example of what you are trying to achieve would
allow to show the D way.



What happens with your code example for the struct:
```
struct S
{
ulong[] a;
@E(0) const int b=1;
void v() const {return;}
int v(int i) const {return i+1;}
}

```

Did I get the value/function body?

Even if get that some day, what about function/value declarations 
in the free scope (module scope)?


A realistic scenario would be mocking, you read in the 
declaration of the type to test and create mock variables for the 
variables referenced in the function body to decouple it from 
other modules.


Re: Get the code of any D-entity as string?

2020-12-27 Thread sighoya via Digitalmars-d-learn

On Sunday, 27 December 2020 at 04:13:53 UTC, Max Haughton wrote:
Not possible although implementing as a __trait would be about 
15 lines I think.




I think that too, and it would nicely reuse the work of the 
compiler to parse the whole project.


I think read only AST access in some form would actually be 
quite nice, if not for dmd's AST being fuckugly (the hierarchy 
is fine but it's more gcc than clang)


The point is, once we have that we can decide ourselves which 
framework is the best for meta modelling.


Is it pure string manipulation or token stream manipulation à la 
Rust or an AST manipulation à la Nim/Scala. It can be all defined 
on top.





Re: Get the code of any D-entity as string?

2020-12-27 Thread sighoya via Digitalmars-d-learn

On Saturday, 26 December 2020 at 21:45:41 UTC, Basile B. wrote:

struct E {int a;}
struct S
{
ulong[] a;
@E(0) const int b;
void v() const {}
void v(int) const {}
}

string getDeclaration(T)()
if (is(T == struct))
{
import std.traits, std.meta;
string result = "struct " ~ T.stringof ~ " {\n";
static foreach (m; __traits(allMembers, T))
{{
static if (isCallable!(__traits(getMember, T, m)))
alias sym = __traits(getOverloads, T, m);
else
alias sym = AliasSeq!(__traits(getMember, T, m));
static foreach (s; sym)
{
result ~= "";
static foreach (a; __traits(getAttributes, s))
result ~= "@" ~ a.stringof ~ " ";
static if (is(typeof(s)))
result ~= typeof(s).stringof ~ " " ~ m ~ ";\n";
}
}}
result ~= "}";
return result;
}

pragma(msg, getDeclaration!S);
---


Thanks a lot, retrieving type declarations as string is better 
than nothing.
But it is still not enough, for instance retrieving the 
expressions of struct fields as string and also recursively 
resolving the expressions of the variables in the string 
expression as string.


This is also a limitation in Nim macros, I think, you can't 
capture values outside the input scope.


Re: Get the code of any D-entity as string?

2020-12-26 Thread sighoya via Digitalmars-d-learn

On Friday, 25 December 2020 at 23:04:15 UTC, Ali Çehreli wrote:

I am probably misunderstanding it but there is the .stringof 
property for all types: T.stringof.


But does stringof really print the declaration as string and not 
the type name itself?


I found: https://dlang.org/spec/property.html#stringof

I am probably stating the obvious but you normally import the 
interesting modules of that library anyway and the type 
information is available that way.


Ali


Well, certainly, yes. But only if `stringof` would do the job. 
The best thing would be to retrieve whole modules (abstract 
files) as string. On top of that we can retrieve any value/type 
declaration.





Get the code of any D-entity as string?

2020-12-25 Thread sighoya via Digitalmars-d-learn

I've read a bit in Dlang traits.

It now has the ability to retrieve all method signatures of an 
overload set.

Big plus from me.

Is generally possible to get the declaration of a 
type/module/value as string in traits?


I didn't have any concrete use case for it, but it would 
essentially allow us to reflect over any code (we may have to 
respect privacy, of course).


On top of that, people could write their own token or ast 
frameworks as library solutions.


Further, most of the trait functionality given in the trait 
library could be simply implemented as a library solution.


I don't know D enough to be sure it isn't yet possible. 
Theoretically, we could read all files in a source folder, but I 
want also to read declarations from types outside my source 
folders, e.g. from those located in dyn libs.


Re: C++ or D?

2020-12-25 Thread sighoya via Digitalmars-d-learn

On Thursday, 24 December 2020 at 08:36:54 UTC, RSY wrote:
You can use GC, you can disable it, you can use malloc, it 
suits all your need!


Not to forget the availability of refcounted (shared) and unique 
ptr too in D.






Re: Why is creating of if Expressions not allowed?

2019-03-24 Thread sighoya via Digitalmars-d-learn

On Sunday, 24 March 2019 at 18:59:45 UTC, Adam D. Ruppe wrote:

Think of mixin() not as pasting code per se, but pasting an AST 
node inside the compiler's data structures. It must be a 
complete node of that tree that can be substituted in.


And because AST Nodes aren't expressions means you can't pass 
them. This makes sense.


I would really like to use normal mixin templates for these 
things, but why I can't insert only declarations with mixin 
templates?


Sure, I can use q{} for better syntax highlighting in string 
mixins but I can't expand args inside them which I can however 
with mixin templates.




Re: Why is creating of if Expressions not allowed?

2019-03-24 Thread sighoya via Digitalmars-d-learn

On Sunday, 24 March 2019 at 18:43:51 UTC, Paul Backus wrote:
You can't return the result of a string mixin from a function. 
Instead, return a string from your `GenIf` function, and mix it 
in at the call site:


string GenIf()
{
return "if (true) { return true; } else { return false; }";
}

bool testFunction()
{
mixin(GenIf());
}


Thanks for mentioning this, this was where I looking for.


Re: Why is creating of if Expressions not allowed?

2019-03-24 Thread sighoya via Digitalmars-d-learn

On Sunday, 24 March 2019 at 16:57:25 UTC, Rémy Mouëza wrote:

On Sunday, 24 March 2019 at 16:18:49 UTC, sighoya wrote:

Why

auto GenIf()()
{
return mixin("if(true) { return true;} else {return 
false;}");

}

public bool testFunction2()
{
GenIf!();
}


gives me:

onlineapp.d-mixin-3(3): Error: expression expected, not if
onlineapp.d(8): Error: template instance `onlineapp.GenIf!()` 
error instantiating


Because D uses if statements, no if expressions.
The equivalent of an if expression is the ternary operator:
bool-condition ? if-true : if-false;


Hmm..., sounds like bad news. Is there any mixin technology for 
statements?




Why is creating of if Expressions not allowed?

2019-03-24 Thread sighoya via Digitalmars-d-learn

Why

auto GenIf()()
{
return mixin("if(true) { return true;} else {return false;}");
}

public bool testFunction2()
{
GenIf!();
}


gives me:

onlineapp.d-mixin-3(3): Error: expression expected, not if
onlineapp.d(8): Error: template instance `onlineapp.GenIf!()` 
error instantiating





Re: Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn

On Tuesday, 3 October 2017 at 15:52:52 UTC, sighoya wrote:

On Tuesday, 3 October 2017 at 15:30:52 UTC, Daniel Kozak wrote:

writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)()));

Dne 3. 10. 2017 3:55 odpoledne napsal uživatel "sighoya via 
Digitalmars-d-learn" <digitalmars-d-learn@puremagic.com>:


But when I write this to:

writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)));

it complains by:

test.d(11): Error: template instance T!(S!int) does not match 
template

declaration Bar(R, S)
test.d(11): Error: template instance T!(S!int) does not match 
template

declaration Bar(R, S)
test.d(17): Error: template instance test.bar!(Bar, Foo, int) 
error

instantiating


I still get

test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(18): Error: template instance test.bar!(Bar, Foo, int) 
error instantiating



by

struct Foo(T) {
T value;
}

struct Bar (R,S) {
R!S fooint;
}


//T!S foo(S, alias T)(T!S v) { return v; }
T!(S!R) bar(alias T,alias S,R)(T!(S!R) v) {return v;}


void main() {
import std.stdio;   
//writeln(foo!(int, Foo)(Foo!int(1)));
//writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)));
writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)()));
}


Thanks!!!


Re: Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn

On Tuesday, 3 October 2017 at 15:30:52 UTC, Daniel Kozak wrote:

writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)()));

Dne 3. 10. 2017 3:55 odpoledne napsal uživatel "sighoya via 
Digitalmars-d-learn" <digitalmars-d-learn@puremagic.com>:


But when I write this to:

writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)));

it complains by:

test.d(11): Error: template instance T!(S!int) does not match 
template

declaration Bar(R, S)
test.d(11): Error: template instance T!(S!int) does not match 
template

declaration Bar(R, S)
test.d(17): Error: template instance test.bar!(Bar, Foo, int) 
error

instantiating


I still get

test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(18): Error: template instance test.bar!(Bar, Foo, int) 
error instantiating



by

struct Foo(T) {
T value;
}

struct Bar (R,S) {
R!S fooint;
}


//T!S foo(S, alias T)(T!S v) { return v; }
T!(S!R) bar(alias T,alias S,R)(T!(S!R) v) {return v;}


void main() {
import std.stdio;   
//writeln(foo!(int, Foo)(Foo!int(1)));
//writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)));
writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)()));
}




Re: Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn

But when I write this to:

writeln(bar!(Bar,Foo,int)(Bar!(Foo,int)));

it complains by:

test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(11): Error: template instance T!(S!int) does not match 
template declaration Bar(R, S)
test.d(17): Error: template instance test.bar!(Bar, Foo, int) 
error instantiating





Re: Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn

Thanks,
How do I construct such a type. I don't get it done right with:

struct Foo(T) {
T value;
}

struct Bar (R,S) {
R!S fooint;
}

T!(S!R) bar(alias T,alias S,R)(T!(S!R) v) {return v;}


void main() {
import std.stdio;   
writeln(bar!(Bar,Foo,int)(Bar!(Foo!int(1.0;
}




Re: Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn
On Tuesday, 3 October 2017 at 12:09:04 UTC, rikki cattermole 
wrote:

On 03/10/2017 1:05 PM, sighoya wrote:

Especially, I mean something like

T foo(S,T)(T i)
{
     ...
}


struct Foo(T) {
T value;
}

T!S foo(S, alias T)(T!S v) { return v; }


void main() {
import std.stdio;   
writeln(foo!(int, Foo)(Foo!int(1)));
}


Cool, but it seems that only a nesting of two is allowed, right?
This one gives an error:

T!S!R bar(alias T,alias S,R)(T!S!R v) {return v;}
Error: multiple ! arguments are not allowed




Does D support nested Templates aka Higher Kinded Polymorphism?

2017-10-03 Thread sighoya via Digitalmars-d-learn

Especially, I mean something like

T foo(S,T)(T i)
{
...
}