Re: Generically call a function on Variant's payload?
On Monday, August 20, 2018 8:29:30 PM MDT Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > On 08/20/2018 04:34 PM, Jonathan M Davis wrote: > > foreach(T; TypesThatVariantHolds) > > Yea, that's what I would've just done, but I wanted to support > user-created types not already known to my library. > > > You > > can't just call functions on completely unknown types, because the > > compiler wouldn't know what code to generate or what to link against. > > Right. D's templates have really spoiled me. Because of them, I've grown > accustomed to invoking functions on unknown types ;) > > But you're right, that's not going to work for runtime dispatch without > enumerating each possible type. Even if I try (like I was thinking) to > provide a templated function to convert any of the concrete types to an > internal-only supertype, I'd still need something to runtime dispatch to > the right template instance. Darn. > > A lot of times, I really wish I could introspect across *all* linked > modules, not just specific ones. Ex: "Hey compiler, give me a > compile-time list of ALL types in this program with UDA @xyz". Then > things like this could be built out of that. No need to worry about > unknown types/symbols because they would all be known and a finite list > could always be constructed. > > Although, what would REALLY be nice is if, for every type, the compiler > built a list of every member and how to access it (which...really it has > to do anyway), but then uses that info to build a master runtime > dispatch system. Types such as Variant already have runtime knowledge of > what type is currently being held, so that info could be passed to the > compiler-generated "master runtime dispatch" system along with what > member to invoke/access. > > Come to think of it...aren't I just describing standard run-of-the-mill > runtime reflection? I mean, hasn't Java already been able to do that for > ages? But then, in Java everything is already part of the class > hierarchy anyway so maybe that's why it's possible there? Runtime reflection is theoretically possible in D, but it requires generating the appropriate stuff for every type involved so that the runtime stuff has something to work with. Java built all of that into the language and has the JVM to boot, which fundamentally changes some of what can be done. With D, we're basically in exactly the same boat as C or C++ except that we have better compile-time type introspection. In principle, a runtime reflection facility could be built using that, but even if it were part of Phobos, it would still have to be opt-in. So, I don't know how useful such a solution would ever be outside of very specific use cases. Regardless, given that D's object files, linking, etc. are using the C tools, it was never going to be the case that Java-style runtime reflection would be built in to D like it is with Java. - Jonathan M Davis
Re: Generically call a function on Variant's payload?
On 08/20/2018 04:34 PM, Jonathan M Davis wrote: foreach(T; TypesThatVariantHolds) Yea, that's what I would've just done, but I wanted to support user-created types not already known to my library. You can't just call functions on completely unknown types, because the compiler wouldn't know what code to generate or what to link against. Right. D's templates have really spoiled me. Because of them, I've grown accustomed to invoking functions on unknown types ;) But you're right, that's not going to work for runtime dispatch without enumerating each possible type. Even if I try (like I was thinking) to provide a templated function to convert any of the concrete types to an internal-only supertype, I'd still need something to runtime dispatch to the right template instance. Darn. A lot of times, I really wish I could introspect across *all* linked modules, not just specific ones. Ex: "Hey compiler, give me a compile-time list of ALL types in this program with UDA @xyz". Then things like this could be built out of that. No need to worry about unknown types/symbols because they would all be known and a finite list could always be constructed. Although, what would REALLY be nice is if, for every type, the compiler built a list of every member and how to access it (which...really it has to do anyway), but then uses that info to build a master runtime dispatch system. Types such as Variant already have runtime knowledge of what type is currently being held, so that info could be passed to the compiler-generated "master runtime dispatch" system along with what member to invoke/access. Come to think of it...aren't I just describing standard run-of-the-mill runtime reflection? I mean, hasn't Java already been able to do that for ages? But then, in Java everything is already part of the class hierarchy anyway so maybe that's why it's possible there?
Re: D need an ORM library!
On Monday, 20 August 2018 at 23:24:04 UTC, Matthias Klumpp wrote: On Monday, 20 August 2018 at 15:58:37 UTC, Jesse Phillips wrote: [...] There are a number of things out there, but personally don't know there state or simplicity. 2016 there was a talk: http://dconf.org/2016/talks/nowak.html But personally I preferred this one: http://dconf.org/2016/talks/smith.html https://github.com/cruisercoder/dstddb This all looks very dead. Is there any project still alive? The only effort that still seems to be actively developed as far as I can see is hunt-entity... And I agree, SQLAlchemy is pretty great! yeah, Only entity is likely a living ORM implementation in D. But, it's API is too complicated, and API is not stable from my experience. SQLAlchemy is very great, and I remember that in D wiki has mentioned this, but the status is "Proposed Project Mentors: TBA".
Re: Auto keyword and when to use it
On Monday, 20 August 2018 at 17:24:19 UTC, QueenSvetlana wrote: I'm struggling to understand what the auto keyword is for and it's appropriate uses. From research, it seems to share the same capabilities as the var keyword in C#. auto is one of the most misunderstood understood features in D. By that I mean, everyone understands the effect of auto, but aren't always accurate in describing it. In D, every variable must have a storage class. The automatic storage class is the default and is never specified in the declaration: int x = 10; Other storage classes are const, immutable, and shared. These are also type constructors, so they become part of the type: const int y = 11; // type is const(int) immutable int z = 12; // type is immutable(int) shared int s = 13; // type is shared(int) D allows the type to be dropped in declarations that include an initializer. In those cases, the type will be inferred: const y = 11; // type is const(int) immutable z = 12; // type is immutable(int) shared s = 13; // type is shared(int) You can also drop the type in declarations with automatic storage, but `x = 10;` is not allowed as a variable declaration. You must include at minimum a type or a storage class. That's where auto comes in: auto x = 10; // type is int So that's all it is. It's nothing special. It just means you're declaring a variable with the default storage class and want the compiler to infer the type. So the question 'when should I use auto' is probably the wrong way to look at it. 'When should I use type inference' is a better way to frame it. And the answer to that is that there is no right answer. I tend to use type inference liberally, almost always with const/immutbale locals, though I tend to use auto only when the type name is longer than four characters. For me, it's a nice way to save keystrokes. Some take a dim view of that approach and prefer to use it only when they actually require type inference. I mostly program alone, though, and I have a number of habits others may label 'bad', so I'm happy with my approach.
Re: D need an ORM library!
On Monday, 20 August 2018 at 15:58:37 UTC, Jesse Phillips wrote: [...] There are a number of things out there, but personally don't know there state or simplicity. 2016 there was a talk: http://dconf.org/2016/talks/nowak.html But personally I preferred this one: http://dconf.org/2016/talks/smith.html https://github.com/cruisercoder/dstddb This all looks very dead. Is there any project still alive? The only effort that still seems to be actively developed as far as I can see is hunt-entity... And I agree, SQLAlchemy is pretty great!
Re: Pure opEquals in a class
On Monday, 20 August 2018 at 19:36:15 UTC, werter wrote: The code below doesn't work. Is it possible to make a pure opEquals in a class? [...] pure bool opEquals(const A rhs) const { return b == rhs.b; } It doesn't work because `rhs` has the wrong type. It must be `Object`. override pure bool opEquals(const Object rhs) const { const A a = cast(A) rhs; return b == a.b; }
Re: Generically call a function on Variant's payload?
On Monday, August 20, 2018 1:38:13 PM MDT Nick Sabalausky (Abscissa) via Digitalmars-d-learn wrote: > There are a bunch of discriminated union types available for D, but the > only one I'm aware of that *doesn't* require a finite-sized list of > types known ahead-of-time is Phobos's Variant. The only problem is > calling a function on a type not already known ahead-of-time. Maybe > that's unsolvable? If so, then I'll fallback to the std.digest approach. > But I'd prefer to avoid that, if possible. It can be done if you know the list of types ahead of time, but you basically have to check which type it is at runtime and then pick which code to run based on that type, which means that you're essentially duplicating a portion of the code for every type - though depending, it would be possible to do something like templatize the code so that you don't have to explicitly dulpicate it. But in the end, aside from using classes, if you're using a variant type, I think that you're stuck doing something like // exact API made up here rather than bothering to take the type to look up // Variant's API. void popFront() { foreach(T; TypesThatVariantHolds) { if(_variant.contains!T) { auto v = _variant.get!T; v.popFront(); return; } } } On the other hand, if you don't know the exact list of types ahead of time or require that the code calling this code tell you which type to use, then you're pretty much stuck using something like classes or delegates. You can't just call functions on completely unknown types, because the compiler wouldn't know what code to generate or what to link against. - Jonathan M Davis
Re: Trouble with LDC2 and definition file to hide console?
For LDC, just rename your main() to WinMain(). Or alternatively, `-L/SUBSYSTEM:WINDOWS -L/ENTRY:mainCRTStartup` in the LDC cmdline.
Re: Generically call a function on Variant's payload?
On 08/19/2018 11:31 PM, Paul Backus wrote: You are basically reinventing OOP here. Yes, I am. Deliberately, in fact. Class inheritance is my backup plan, though. My use-case is actually very, very similar to std.digest: There are various benefits to using a template-and-constraint based interface. But one notable downside is the inability to handle the situation where the actual type needed is only known at runtime. In std.digest, this dilemma is dealt with by duplicating the entire interface in BOTH template/constraint AND class-inheritance varieties. Additionally, an important thing to note in the case of std.digest is that `isDigest!T` returns FALSE for types using the OOP version of the interface. I think there is (arguably) a certain merit in that: The OOP interface obviously uses classes, whereas (in order to obtain the full potential benefits of a template-and-constraint approach) the template interface uses (and even requires) structs. Because of this, instances should be constructed differently ("T instance;" vs "T instance = new T();"). Thus, any generic code that wants to handle ANY digest type must be very careful to mind this distinction whenever creating new instances. Presumably, this may be why std.digest chose to NOT let OO digests satisfy the template-oriented isDigest. And then std.digest also needs WrapperDigest, needed to convert a template-style digest to OO-style. So...while std.digest succeeds at offering the best-of-both-worlds between template and OO approaches, it also creates a whole new mess via completely duplicated interfaces that aren't 100% compatible. I want to see if I can do better. So back to the root of the problem: We have a bunch of types, including user-defined types we don't have advance knowledge of. And we need a type which can hold any of them at runtime. AFAIK, there are two classic ways to do that: One is OOP, the other is an unbounded discriminated union (a variant). Unlike class-based inheritance, a variant CAN be implemented as a struct. So, at least in theory, a variant-based type could potentially be made which implements the *true* template-based interface, eliminating the need for duplicate APIs and the mess that entails. There are a bunch of discriminated union types available for D, but the only one I'm aware of that *doesn't* require a finite-sized list of types known ahead-of-time is Phobos's Variant. The only problem is calling a function on a type not already known ahead-of-time. Maybe that's unsolvable? If so, then I'll fallback to the std.digest approach. But I'd prefer to avoid that, if possible.
Pure opEquals in a class
The code below doesn't work. Is it possible to make a pure opEquals in a class? void main() { class A { bool a; int b; this(bool g, int h) { a = g; b = h; } pure bool opEquals(const A rhs) const { return b == rhs.b; } } A a = new A(true, 5); A b = new A(false, 5); assert(a == b); //fails }
Re: Trouble with LDC2 and definition file to hide console?
On Monday, 20 August 2018 at 13:49:19 UTC, rikki cattermole wrote: That is for Optlink not for MSVC link which ldc uses. Exactly. For LDC, just rename your main() to WinMain().
Dub and it's build directory
Hi, Given a package X, let us assume it's a library such that X = unit- threaded, we find that in the ~/.dub/packages directory there is: .dub/packages/unit-threaded-0.7.51/unit-threaded/gen_ut_main* .dub/packages/unit-threaded-0.7.51/unit-threaded/libunit-threaded.a These are the compilation products from the last undertaken compilation and therefore more or less totally useless for anyone using more than one D compiler. Fortunately we find that there is a .dub directory with: unit-threaded-0.7.51/unit-threaded/.dub ├── build │ ├── gen_ut_main-debug-linux.posix-x86_64-dmd_2081-5610CAAD59972DC7A3346FE37EEC66C8 │ │ ├── gen_ut_main │ │ └── gen_ut_main.o │ ├── gen_ut_main-debug-linux.posix-x86_64-ldc_2081-02C0EA3AA341F3D071FE5E15E09EC021 │ │ └── gen_ut_main │ ├── gen_ut_main-release-linux.posix-x86_64-dmd_2081-A8C2C7980309FFAFE08C15D3B29DE3CC │ │ ├── gen_ut_main │ │ └── gen_ut_main.o │ ├── gen_ut_main-release-linux.posix-x86_64-ldc_2081-78BBAEC37FCFC878CC8215379A7D854B │ │ └── gen_ut_main │ ├── library-debug-linux.posix-x86_64-dmd_2081-5610CAAD59972DC7A3346FE37EEC66C8 │ │ └── libunit-threaded.a │ ├── library-debug-linux.posix-x86_64-ldc_2081-02C0EA3AA341F3D071FE5E15E09EC021 │ │ └── libunit-threaded.a │ ├── library-release-linux.posix-x86_64-dmd_2081-A8C2C7980309FFAFE08C15D3B29DE3CC │ │ └── libunit-threaded.a │ └── library-release-linux.posix-x86_64-ldc_2081-78BBAEC37FCFC878CC8215379A7D854B │ └── libunit-threaded.a └── dub.json OK, so this is now actually useful stuff for people using Dub. Clearly the directory names are dash separated components: · configuration · build type · dot separated platform specification · architecture · underscore separated compiler name and major/minor version number · some bizarre psuedo-random number So the questions are: 1. How does Dub find the compiler version number, in this case 2.081, given that neither DMD or LDC seem to have a way of delivering only the version number. 2. What is the pseudo-random number, and how is it calculated? -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: D need an ORM library!
On Mon, 2018-08-20 at 15:58 +, Jesse Phillips via Digitalmars-d- learn wrote: > On Monday, 20 August 2018 at 02:30:16 UTC, binghoo dang wrote: > > hi, > > > > I thinks D need an ORM library for Sqlite/Mysql/PostgreSQL, > > entity currently support all the three targets, but entity's > > API is too complex and cumbersome for using. Can I suggest that SQLAlchemy is excellent. It has the full on ORM for those that want it, but also an expression language so you do not have to write SQL in strings if you are not using the ORM. Being able to write Python that generated SQL (Builder pattern) has made working with SQLite almost a joy. > > Is there a more light-weight and simpler implementation like > > ActiveAndroid ? > > > > Thanks! > > > > > > --- > > > > Binghoo Dang > > There are a number of things out there, but personally don't know > there state or simplicity. > > 2016 there was a talk: http://dconf.org/2016/talks/nowak.html > > But personally I preferred this one: > http://dconf.org/2016/talks/smith.html > https://github.com/cruisercoder/dstddb -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Auto keyword and when to use it
On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote: Great! So I can't declare class level variables with auto, correct? only local method variables? You can, globals, class members: class Foo { auto bar = "hi"; } Foo.bar will be of string type here, because "hi" is a string. What you can't do is: class Foo { auto bar; } because now the compiler doesn't know what type 'bar' is supposed to be.
Re: Auto keyword and when to use it
On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote: Great! So I can't declare class level variables with auto, correct? only local method variables? You can use auto if you're setting the class level variable to a default. class X { auto i = 42; // i will be an int }
Re: Auto keyword and when to use it
Great! So I can't declare class level variables with auto, correct? only local method variables?
Re: Deduce type of struct in function arguments
On Monday, 20 August 2018 at 12:33:34 UTC, Andrey wrote: On Monday, 20 August 2018 at 11:38:39 UTC, Paul Backus wrote: Create an overload of foo that takes two arguments and combines them into a `Data` struct internally: void foo(int a, string text) { Data data = {a, text}; foo(data); } Hmm, not very good solution. In C++ you can not to write type and compiler will deduce it automatically. In D, as I understand, this feature isn't supported. ... yet. Though you can vote for this DIP and show your support there: https://github.com/dlang/DIPs/pull/71 It even comes with an implementation in DMD already: https://github.com/dlang/dmd/pull/8460
Re: Auto keyword and when to use it
On Monday, 20 August 2018 at 17:24:19 UTC, QueenSvetlana wrote: I'm new to D programming, but have I have a background with Python. I'm struggling to understand what the auto keyword is for and it's appropriate uses. From research, it seems to share the same capabilities as the var keyword in C#. From the C# documentation, it states: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var ... variables that are declared at method scope can have an implicit "type" var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type. Is the same true for auto? For example, if I have a class Person, I might have attributes such as FirstName, LastName which should obviously be strings but will D allow me to declare class level attributes with auto? C# doesn't allow this. It basically works like C#. auto x = "hi"; will make x a string. But if you later try: x = 5; it will throw an error, because x is a string. It's used to save you the typing of the type, it doesn't make the language dynamically typed.
Auto keyword and when to use it
I'm new to D programming, but have I have a background with Python. I'm struggling to understand what the auto keyword is for and it's appropriate uses. From research, it seems to share the same capabilities as the var keyword in C#. From the C# documentation, it states: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var ... variables that are declared at method scope can have an implicit "type" var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type. Is the same true for auto? For example, if I have a class Person, I might have attributes such as FirstName, LastName which should obviously be strings but will D allow me to declare class level attributes with auto? C# doesn't allow this.
Re: UDA on double nested struct
On Monday, 20 August 2018 at 16:27:55 UTC, Basile B. wrote: Hello, it works fine here. Maybe there was another error that you removed when you have minimized the example. See https://run.dlang.io/is/ZrW7kI, that says that the example works since 2.068.2. Although that are are possibility that it was broken before a patch release, since only latest path of a minor release is tested on the site, in which case updating the compiler would fix the issue. Wow, that is really nice, running all compilers at once. Thanks for showing that. Anyway, I found out that the problem was that the `Hover` struct was named `hover` in my code. See https://run.dlang.io/is/3dLli6 In that case the inner hover takes precedence over the enum hover. Is that wanted behaviour? I would at minimum expect an ambiguity error.
Re: Make function alias
On Monday, 20 August 2018 at 13:14:14 UTC, Andrey wrote: Hello, I want to make an alias to function "std.stdio.writeln" and "std.stdio.write" and use it like: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(); text.print(); } Unfortunately, it doesn't work... Also tried with "enum print ..." but also no success. How to do it correctly? If it's about having a concise syntax then you can do: --- import std.stdio; void main() { log!false("meep ! "); log!true("meep meep !"); } static void log(bool newline = true)(string text) { alias print = (a) => newline ? writeln(a) : write(a); print(text); } --- although this is like static if {} () else {}
Re: UDA on double nested struct
On Monday, 20 August 2018 at 16:16:04 UTC, Sebastiaan Koppe wrote: Hey, I am trying to get UDAs from a doubly nested struct, to no avail: code --- import std.traits : hasUDA; enum hover; struct Style { struct Root { auto margin = "10px"; auto backgroundColor = "white"; @hover struct Hover { auto backgroundColor = "gray"; } } } pragma(msg, hasUDA!(Style.Root.Hover, hover)); --- returns false. Bug or no? (Yes, I am generating css at compile time.) Putting it on Root or on Style works as intended; Hello, it works fine here. Maybe there was another error that you removed when you have minimized the example. See https://run.dlang.io/is/ZrW7kI, that says that the example works since 2.068.2. Although that are are possibility that it was broken before a patch release, since only latest path of a minor release is tested on the site, in which case updating the compiler would fix the issue.
UDA on double nested struct
Hey, I am trying to get UDAs from a doubly nested struct, to no avail: code --- import std.traits : hasUDA; enum hover; struct Style { struct Root { auto margin = "10px"; auto backgroundColor = "white"; @hover struct Hover { auto backgroundColor = "gray"; } } } pragma(msg, hasUDA!(Style.Root.Hover, hover)); --- returns false. Bug or no? (Yes, I am generating css at compile time.) Putting it on Root or on Style works as intended;
Re: Make function alias
On Monday, 20 August 2018 at 13:35:07 UTC, ag0aep6g wrote: On 08/20/2018 03:14 PM, Andrey wrote: Thanks everybody for your answers.
Re: D need an ORM library!
On Monday, 20 August 2018 at 02:30:16 UTC, binghoo dang wrote: hi, I thinks D need an ORM library for Sqlite/Mysql/PostgreSQL, entity currently support all the three targets, but entity's API is too complex and cumbersome for using. Is there a more light-weight and simpler implementation like ActiveAndroid ? Thanks! --- Binghoo Dang There are a number of things out there, but personally don't know there state or simplicity. 2016 there was a talk: http://dconf.org/2016/talks/nowak.html But personally I preferred this one: http://dconf.org/2016/talks/smith.html https://github.com/cruisercoder/dstddb
Re: Trouble with LDC2 and definition file to hide console?
On 21/08/2018 1:42 AM, spikespaz wrote: I am trying to add a *.def file to my program to hide the console window on launch, as it doesn't need to display anything to function. It is a Windows only application. I saw at this post (https://forum.dlang.org/post/ilj5vn$ef4$1...@digitalmars.com) that I could either use a linker flag, -L/exet:nt/su:windows, or add a module definition file. I decided on the definition file. EXETYPE NT SUBSYSTEM WINDOWS That is for Optlink not for MSVC link which ldc uses.
Re: Trouble with LDC2 and definition file to hide console?
On Monday, 20 August 2018 at 13:42:58 UTC, spikespaz wrote: I am trying to add a *.def file to my program to hide the console window on launch, as it doesn't need to display anything to function. It is a Windows only application. [...] Also adding that the linker flag I have stated above also is ignored by the linker. LINK : warning LNK4044: unrecognized option '/exet:nt/su:windows'; ignored
Trouble with LDC2 and definition file to hide console?
I am trying to add a *.def file to my program to hide the console window on launch, as it doesn't need to display anything to function. It is a Windows only application. I saw at this post (https://forum.dlang.org/post/ilj5vn$ef4$1...@digitalmars.com) that I could either use a linker flag, -L/exet:nt/su:windows, or add a module definition file. I decided on the definition file. EXETYPE NT SUBSYSTEM WINDOWS I have this file named deflector.def, and I compile with the command as follows. ldc2 source/* -of="build/SearchDeflector-x86.exe" -O3 -ffast-math -release All of my source code and the *.def file is in the source/ directory. I am not using DUB. The issue when compiling says that those two definitions(?) aren't supported for my target. That doesn't make sense because I am using the MSVC linker with LDC2. source\deflector.def(1) : warning LNK4017: EXETYPE statement not supported for the target platform; ignored source\deflector.def(2) : warning LNK4017: SUBSYSTEM statement not supported for the target platform; ignored Any help would be appreciated. I would also like to know how to add a PNG or ICO file to my compiled executable. I have icons in the resolutions of 16, 32, 64, 128, 256. Currently I'm adding them in using GitHub's RCEDIT tool (https://github.com/electron/rcedit) but I would like a more proper way.
Re: Make function alias
On 08/20/2018 03:14 PM, Andrey wrote: Hello, I want to make an alias to function "std.stdio.writeln" and "std.stdio.write" and use it like: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(); text.print(); } Unfortunately, it doesn't work... Also tried with "enum print ..." but also no success. How to do it correctly? `writeln` is a template, so you can't do ``. You'd have to instantiate the template before you can get the function pointer: `!T`. Even then you can't make an alias of that. `!T` is a function pointer, which is a value. But aliases work on types and symbols, not values. If you manage to obtain aliases, you won't be able to use the ternary operator on them. Being an expression, `foo ? bar : baz` works on values. You can't use it with function aliases. You have to commit to either function aliases or function pointers (values). With aliases (no address-of operator, no ternary operator, `print` is not a template): void log(bool newline = true)(string text) { static if (newline) alias print = writeln; else alias print = writeln; print(text); /* Can't use UFCS with a local `print`, so `text.print()` doesn't work. */ } With function pointers (have to instantiate `writeln`, `write`, and `print): void log(bool newline = true)(string text) { enum print(T ...) = newline ? !T : !T; print!string(text); /* No IFTI, because `print` isn't a function template. */ }
Re: Make function alias
On Monday, 20 August 2018 at 13:14:14 UTC, Andrey wrote: Hello, I want to make an alias to function "std.stdio.writeln" and "std.stdio.write" and use it like: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(); text.print(); } Unfortunately, it doesn't work... Also tried with "enum print ..." but also no success. How to do it correctly? Since newline is a compile-time parameter, you can use `static if`: static if (newline) { alias print = writeln; } else { alias print = write; } Note that since this alias is local to the function, you cannot use it with UFCS, so you will have to write `print(text)` instead of `text.print()`. Full example: https://run.dlang.io/is/SrBJdk
Re: Make function alias
On Monday, 20 August 2018 at 13:22:02 UTC, Andrey wrote: On Monday, 20 August 2018 at 13:14:14 UTC, Andrey wrote: Mistake... this is: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(text); text.print(); } static void log(bool newline = true)(string text) { static if(newline)alias print = writeln; else alias print = write; _file.print(text); text.print(); }
Re: Make function alias
On Monday, 20 August 2018 at 13:14:14 UTC, Andrey wrote: Mistake... this is: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(text); text.print(); }
Re: Deduce type of struct in function arguments
On Monday, 20 August 2018 at 12:33:34 UTC, Andrey wrote: On Monday, 20 August 2018 at 11:38:39 UTC, Paul Backus wrote: Create an overload of foo that takes two arguments and combines them into a `Data` struct internally: void foo(int a, string text) { Data data = {a, text}; foo(data); } Hmm, not very good solution. In C++ you can not to write type and compiler will deduce it automatically. In D, as I understand, this feature isn't supported. Yes, D's syntax for structure literals requires you to write the name of the type: https://dlang.org/spec/struct.html#struct-literal If the name of the type is too cumbersome to write out, you can use an alias: alias ShortName = MyLongAndComplicatedType!(PossiblyWith, TemplateArguments); foo(ShortName(a, text));
Make function alias
Hello, I want to make an alias to function "std.stdio.writeln" and "std.stdio.write" and use it like: static void log(bool newline = true)(string text) { alias print(T...) = newline ? : _file.print(); text.print(); } Unfortunately, it doesn't work... Also tried with "enum print ..." but also no success. How to do it correctly?
Re: Deduce type of struct in function arguments
On Monday, 20 August 2018 at 11:38:39 UTC, Paul Backus wrote: Create an overload of foo that takes two arguments and combines them into a `Data` struct internally: void foo(int a, string text) { Data data = {a, text}; foo(data); } Hmm, not very good solution. In C++ you can not to write type and compiler will deduce it automatically. In D, as I understand, this feature isn't supported.
Re: Deduce type of struct in function arguments
On Monday, 20 August 2018 at 09:23:27 UTC, Andrey wrote: Hello, I have a function and a struct: void foo(ref Data data) { ... } struct Data { int a; string text; } How to pass struct into function without naming its type? This doesn't work: foo({1234, "Hello!"}); Create an overload of foo that takes two arguments and combines them into a `Data` struct internally: void foo(int a, string text) { Data data = {a, text}; foo(data); }
Re: ushort + ushort = int?
On Monday, August 20, 2018 4:29:56 AM MDT Andrey via Digitalmars-d-learn wrote: > On Monday, 20 August 2018 at 09:56:13 UTC, Jonathan M Davis wrote: > > It's a combination of keeping the C semantics (in general, C > > code is valid D code with the same semantics, or it won't > > compile) and the fact that D requires casts for narrowing > > conversions. When you add two shorts in C/C++, it converts them > > to int just like D does. It's just that C/C++ has implicit > > narrowing casts, so if you assign the result to a short, it > > then converts the result to short even if that means that the > > value could be truncated, whereas D requires that you > > explicitly cast to convert to int rather than silently > > truncating. > > > > It does prevent certain classes of problems (e.g. there are > > plenty of bugs in C/C++ due to implicit narrowing conversions), > > but it can also get pretty annoying if you're doing much math > > on integer types smaller than int, and you either know that > > they aren't going to overflow or truncate, or you don't care > > that they will. But if you're only doing math on such small > > integeral types occasionally, then it pretty much just means > > that once in a while, you get briefly annoyed when you forget > > to add a cast, and the compiler yells at you. > > > > - Jonathan M Davis > > Understood. > Is there a workaround to reduce amount of manual casts of input > types T into output T? > May be one can write some module-global operator "plus", > "minus"..? > > Like in C++: > > template > > T operator+(T first, T second) > > > >{ > > > >return static_cast(first + second); > > > >} D only allows overloaded operators to be declared on types, so you can't overload any operators for any built-in types (or any types that you don't control the declaration of for that matter). You could create a wrapper function and use that instead of +. You could even make it use string mixins like opBinary does if you wanted to - e.g. something like short doOp(string op)(short lhs, short rhs) if(op == "+" || op == "-" || op == "*" || op == "/" || op == "%") { mixin("return cast(short)(lhs " ~ op ~ " rhs);"); } val1 = val1.doOp!"+"(val2); but you're not going to be able to get something like val1 = val1 + val2; to work with just short. Alternatively, you could create a wrapper type and use that instead of using short directly. IIRC, the last time that someone was complaining in the main newsgroup about all of the required casts, someone posted a link to something that did that. If the casts are too annoying for you, that would probably be the best solution. - Jonathan M Davis
Re: ushort + ushort = int?
On Monday, 20 August 2018 at 09:56:13 UTC, Jonathan M Davis wrote: It's a combination of keeping the C semantics (in general, C code is valid D code with the same semantics, or it won't compile) and the fact that D requires casts for narrowing conversions. When you add two shorts in C/C++, it converts them to int just like D does. It's just that C/C++ has implicit narrowing casts, so if you assign the result to a short, it then converts the result to short even if that means that the value could be truncated, whereas D requires that you explicitly cast to convert to int rather than silently truncating. It does prevent certain classes of problems (e.g. there are plenty of bugs in C/C++ due to implicit narrowing conversions), but it can also get pretty annoying if you're doing much math on integer types smaller than int, and you either know that they aren't going to overflow or truncate, or you don't care that they will. But if you're only doing math on such small integeral types occasionally, then it pretty much just means that once in a while, you get briefly annoyed when you forget to add a cast, and the compiler yells at you. - Jonathan M Davis Understood. Is there a workaround to reduce amount of manual casts of input types T into output T? May be one can write some module-global operator "plus", "minus"..? Like in C++: template T operator+(T first, T second) { return static_cast(first + second); }
Re: ushort + ushort = int?
On Monday, August 20, 2018 3:19:04 AM MDT Andrey via Digitalmars-d-learn wrote: > On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote: > > Yes. On x86 int's will be faster just an FYI so it does make > > sense to use them for computation. > > Inconveniently always use casts. Why in D one decided to do in > such way? It's a combination of keeping the C semantics (in general, C code is valid D code with the same semantics, or it won't compile) and the fact that D requires casts for narrowing conversions. When you add two shorts in C/C++, it converts them to int just like D does. It's just that C/C++ has implicit narrowing casts, so if you assign the result to a short, it then converts the result to short even if that means that the value could be truncated, whereas D requires that you explicitly cast to convert to int rather than silently truncating. It does prevent certain classes of problems (e.g. there are plenty of bugs in C/C++ due to implicit narrowing conversions), but it can also get pretty annoying if you're doing much math on integer types smaller than int, and you either know that they aren't going to overflow or truncate, or you don't care that they will. But if you're only doing math on such small integeral types occasionally, then it pretty much just means that once in a while, you get briefly annoyed when you forget to add a cast, and the compiler yells at you. - Jonathan M Davis
Re: ushort + ushort = int?
On 20/08/2018 9:19 PM, Andrey wrote: On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote: Yes. On x86 int's will be faster just an FYI so it does make sense to use them for computation. Inconveniently always use casts. Why in D one decided to do in such way? C.
Deduce type of struct in function arguments
Hello, I have a function and a struct: void foo(ref Data data) { ... } struct Data { int a; string text; } How to pass struct into function without naming its type? This doesn't work: foo({1234, "Hello!"});
Re: ushort + ushort = int?
On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote: Yes. On x86 int's will be faster just an FYI so it does make sense to use them for computation. Inconveniently always use casts. Why in D one decided to do in such way?
Re: ushort + ushort = int?
On 20/08/2018 8:48 PM, Andrey wrote: On Monday, 20 August 2018 at 08:42:20 UTC, rikki cattermole wrote: It's called integer promotion and it originates from C. And yes C++ does have such support in some variant (I really don't feel like comparing the two). And I should do? Always use "cast" operator when I operate not with ints? Yes. On x86 int's will be faster just an FYI so it does make sense to use them for computation.
Re: ushort + ushort = int?
On Monday, 20 August 2018 at 08:42:20 UTC, rikki cattermole wrote: It's called integer promotion and it originates from C. And yes C++ does have such support in some variant (I really don't feel like comparing the two). And I should do? Always use "cast" operator when I operate not with ints?
Re: ushort + ushort = int?
On 20/08/2018 8:34 PM, Andrey wrote: Hello, Here is a code that you can execute using online compiler https://run.dlang.io/: import std.stdio; void main() { ushort first = 5; ushort second = 1000; ushort result = first + second; writeln(result); } I hae this error: onlineapp.d(7): Error: cannot implicitly convert expression cast(int)first + cast(int)second of type int to ushort Why they are "int" when I declared them as "ushort"??? ushort + ushort = ushort, not int. In C++ there aren't any such issues... It's called integer promotion and it originates from C. And yes C++ does have such support in some variant (I really don't feel like comparing the two).
ushort + ushort = int?
Hello, Here is a code that you can execute using online compiler https://run.dlang.io/: import std.stdio; void main() { ushort first = 5; ushort second = 1000; ushort result = first + second; writeln(result); } I hae this error: onlineapp.d(7): Error: cannot implicitly convert expression cast(int)first + cast(int)second of type int to ushort Why they are "int" when I declared them as "ushort"??? ushort + ushort = ushort, not int. In C++ there aren't any such issues...