Naming issue importing different function overloads
Hi, There's issue in importing functions I came across some time ago that I wonder if it is a purposeful design or if it is something that will be changed in the future. Say I have module like this: ```d module funs; double myfun(double x) { return x*x; } ``` and I call `myfun` in a function in another module: ```d module call; import funs; double myfun(double y, double x) { return myfun(x)/y; } void main() { import std.stdio: writeln; writeln("Demo myfun(2, 3): ", myfun(2, 3)); } ``` If I attempt to compile this I shall get the error: ``` $ dmd call.d funs.d call.d(8): Error: function call.myfun(double y, double x) is not callable using argument types (double) call.d(8):missing argument for parameter #2: double x ``` Even though the function signatures are different I have to call `myfun` with `funs.myfun(...)` in the `call.d` module. I understand sometimes it's is good practice to do this, but shouldn't I expect the D compiler to be "clever enough" to ignore correct use but detect when function signatures clash and throwing an error with an appropriate message when they do, rather than a cryptic message telling me that the function signature is wrong? In the current situation, you can import `funs.d` and call `myfun` with no issue until you decide to overload it in that module, when you suddenly get errors. If you are not aware of this issue and you are writing a large and highly detailed module, it's an error that seems to come out of nowhere, the module has suddenly lost visibility of the imported function. I guess an alternative is to use `mixin(import("funs.d"));` but you then lose the functionality of the formal `import` statement. Thank you
Re: How to compile Phobos with other D code to create a shared library?
On Friday, 4 June 2021 at 15:19:17 UTC, bachmeier wrote: It requires an R package if you want to call D functions from R. You need to link to R itself if you want to do something like pass a vector from R to D and then access that data from D. Since R is aware of the location of all the underlying libraries, it's easiest to let it generate the dub.sdl for you. I guess you're using the older .C interface [as done here](http://users.stat.umn.edu/~geyer/rc/). Good enough if passing double* and int* pointers to D functions will suffice. Only thing you need to do to initialize the D runtime is add this to your D code ``` struct DllInfo; extern(C) void R_init_libfoo(DllInfo * info) { Runtime.initialize(); } ``` where foo is the name of the library you're loading (foo.so). I've just read the documentation and had a go, **compiling with GDC worked for both `.C` and `.Call`**. I tried with all three compilers DMD, LDC, and GDC, and looked at the outputs with the nm tool. I don't think this matters much but DMD and LDC are more likely to list functions (DMD) or symbols in referenced modules (LDC) as weak symbols. I think the more likely the reason GDC worked is because it is a GNU compiler this has full GLIBC compatibility with reference to the `librt.so.1` `GLIBC_PRIVATE` error. The R ext documentation you kindly referenced says: *"By default, R uses the operating-system-specific dynamic loader to lookup the symbol in all loaded DLLs and the R executable or libraries it is linked to."* and that: *"Registering routines has two main advantages: it provides a faster way to find the address of the entry point via tables stored in the DLL at compilation time, and it provides a run-time check that the entry point is called with the right number of arguments and, optionally, the right argument types."* So registering symbols is not the issue. The error was specific to GLIBC which is probably why the GNU compiler worked. Thank you.
Re: How to compile Phobos with other D code to create a shared library?
On Wednesday, 2 June 2021 at 23:23:58 UTC, bachmeier wrote: Are you aware of my embedr project, which handles all that for you, and does a lot of other stuff? https://embedr.netlify.app If you want to do it yourself, you can see the boilerplate you need to add to call a shared library from R here: https://bitbucket.org/bachmeil/embedr/src/bebf67e5b30cd4163214c7f44f9907e7d7490dc0/R/compile.R#lines-99 If you want to read the R manual, the relevant section is here: https://cran.r-project.org/doc/manuals/r-release/R-exts.html#dyn_002eload-and-dyn_002eunload If you don't do that, it's unlikely to work unless you get lucky. If you want to load foo.so, you need a corresponding R_init_foo function where you call Runtime.initialize. Thanks. Looks like I have some more reading to do. I did know about embedr, but I saw it had dependencies and I wanted a standalone and fully transparent D solution. I'm already calling R routines from D using standalone Rmath and being able to call D from R and D have independent full access to R's internals would be awesome. But your package certainly provides very useful information. The reference to R's dyn.load internals looks useful and relevant and I'll be trying those once I get the time. Probably during the weekend.
Re: How to compile Phobos with other D code to create a shared library?
Doing `Runtime.initialize` is working with Julia but not yet R, I'm getting a clock/GLIBC error ``` Error in dyn.load("rbasic.so") : unable to load shared object 'code/rbasic.so': lib/x86_64-linux-gnu/librt.so.1: undefined symbol: __clock_nanosleep, version GLIBC_PRIVATE ``` do I need to import anything else?
Re: How to compile Phobos with other D code to create a shared library?
On Wednesday, 2 June 2021 at 17:49:49 UTC, Steven Schveighoffer wrote: What's happening is that the dynamic linker is trying to resolve that symbol, but cannot find it in the given library. Try `ldd code/rbasic.so` and see if it tells you the things it is looking for. Many times, you will see "Not found" or something and you know what library to install/look for. I ran `ldd`, it looks as if all the symbols are resolved ``` $ ldd rbasic.so linux-vdso.so.1 (0x7ffe7af56000) libR.so => /lib/libR.so (0x7f269adb8000) libdruntime-ldc-shared.so.94 => /snap/ldc2/170/bin/../lib/libdruntime-ldc-shared.so.94 (0x7f269ac0c000) libblas.so.3 => /lib/x86_64-linux-gnu/libblas.so.3 (0x7f269920d000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x7f26990be000) libreadline.so.8 => /lib/x86_64-linux-gnu/libreadline.so.8 (0x7f269906e000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x7f2698fdc000) liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x7f2698fb3000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x7f2698fa) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x7f2698f84000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x7f2698f7e000) libicuuc.so.66 => /lib/x86_64-linux-gnu/libicuuc.so.66 (0x7f2698d98000) libicui18n.so.66 => /lib/x86_64-linux-gnu/libicui18n.so.66 (0x7f2698a97000) libgomp.so.1 => /lib/x86_64-linux-gnu/libgomp.so.1 (0x7f2698a55000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x7f2698a32000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7f269884) /lib64/ld-linux-x86-64.so.2 (0x7f269b29e000) librt.so.1 => /snap/core/current/lib/x86_64-linux-gnu/librt.so.1 (0x7f2698638000) libgcc_s.so.1 => /snap/core/current/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x7f269842) libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x7f26983f) libicudata.so.66 => /lib/x86_64-linux-gnu/libicudata.so.66 (0x7f269692f000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x7f269674e000) ``` Otherwise, it might be that librt.so.1 seemed to have __clock_nanosleep when it was built, but the librt.so.1 it is loading during runtime does not have it. Are you building on one machine and then running on another? I am building and running on the same machine.
Re: Can we use "ImportC" used yet?
Hi, I'm getting an odd issue with ImportC when I import a header converted with `gcc -E -P ...` some of the types signatures in functions don't come through with their proper names but as `__tagXX` where `XX` is some number. It's got to the point where the type itself might get imported correctly, but the same type in a function might be `__tag28` or some other mangled name so when I create an instance of the proper type and try to call the respective function, I get a type error. Also, with some definitions in the C file, when I try to `#undef` something to get some conditional C definitions to be converted with `gcc -E -P ...`, nothing happens. Thanks.
Re: Can we use "ImportC" used yet?
On Sunday, 17 October 2021 at 04:45:26 UTC, data pulverizer wrote: I ended up defining `typedef struct __float128__ {unsigned long long x[2];} __float128__;` and doing a find and replace for `__float128` which is totally overkill since I won't be using it and according to the documentation, the D compiler doesn't support 128-bit floats yet though it has reserved keywords for it. Many thanks. Decided the best idea to just to comment it out altogether.
Re: Can we use "ImportC" used yet?
I ended up defining `typedef struct __float128__ {unsigned long long x[2];} __float128__;` and doing a find and replace for `__float128` which is totally overkill since I won't be using it and according to the documentation, the D compiler doesn't support 128-bit floats yet though it has reserved keywords for it. Many thanks.
Re: Can we use "ImportC" used yet?
On Saturday, 16 October 2021 at 08:19:41 UTC, rempas wrote: On Saturday, 16 October 2021 at 07:09:16 UTC, jfondren wrote: If I understand correctly you mean compile the original file with gcc (`gcc test_og.c -o test_og.o`) and then link it with DMD (`dmd test.d test_og.o`)? ... While we're on this subject, I've been having similar issues now tried compiling @rempas's example file with: ``` gcc test_og.c -c -o test_og.o dmd test.d test_og.o ``` and get the response: ``` test_og.c(1): Error: identifier or `(` expected test_og.c(6): Error: identifier or `(` expected ``` Platform is Ubuntu 20.04 gcc version 9.30 and dmd version v2.098.0. At first I tried compiling a script with fftw3 and thought it was something wrong with my script but when I tried it with your example, the same thing happened.
Re: Can we use "ImportC" used yet?
Okay wow, this is amazing, I can now call R's standalone math library `Rmath.h` by converting: ``` //r2d_con.c #define __restrict restrict #define __asm__ asm #define __extension__ #define __inline #define __builtin_bswap16 #define __builtin_bswap32 #define __builtin_bswap64 #define MATHLIB_STANDALONE 1 typedef struct _Float128 {unsigned long long x[2];} _Float128; #include "Rmath.h" #include "R_ext/Random.h" ``` ``` //callr import r2d; import std.random: unpredictableSeed; import std.stdio: writeln; void main() { set_seed(unpredictableSeed(), unpredictableSeed()); writeln("rgamma (2, 3): ", rgamma(2, 3)); } ``` Using: ``` gcc -E -P -I"/usr/share/R/include" -lRmath r2d_con.c > r2d.c dmd callr.d -L-lRmath -L-lm && ./callr ``` Okay it's only the standalone library which is a small part of R, but this rocks. The PAHWAHR! Lol.
Re: Can we use "ImportC" used yet?
On Sunday, 17 October 2021 at 10:46:30 UTC, data pulverizer wrote: Okay wow, this is amazing, I can now call R's standalone math library `Rmath.h` by converting ... Sorry you don't need `-lRmath` so the initial call should be: ``` gcc -E -P -I"/usr/share/R/include" r2d_con.c > r2d.c ```
Re: Can we use "ImportC" used yet?
Okay I'm definitely trying to use `importC` rather than the regular `extern(C)` way. I can see where I went wrong. The steps for importC for header files are: 1. Prepend the following directives to `test_og.c` or whatever your interface c script is: ``` #define __restrict restrict #define __asm__ asm #define __extension__ #define __inline #define __builtin_bswap16 #define __builtin_bswap32 #define __builtin_bswap64 ``` 2. Run the commands: ``` gcc -E -P test_og.c > test_c.c dmd test.d test_c.c && ./test ``` which works. Now I've tried the same thing with library `fftw3` and getting: ``` Error: undefined identifier `__float128` ``` Which I guess I have to define somehow in the original c directives?
Re: Can we use "ImportC" used yet?
On Sunday, 24 October 2021 at 05:54:43 UTC, data pulverizer wrote: Actually it's more complicated than that. On construction I do need to call `protect` and call `unprotect` or `unprotect_ptr` when the function in which the object is created returns. At the moment, I'm not even sure (or more likely do not think) that it is suitable to call it as part of the destructor. Anyway, that's an aside. Okay since it's stack allocated it's okay to call `unprotect` in the destructor if the object is a `struct` but not if it is a `class`.
Re: Can we use "ImportC" used yet?
On Saturday, 23 October 2021 at 17:42:32 UTC, data pulverizer wrote: On Saturday, 23 October 2021 at 16:39:08 UTC, data pulverizer wrote: ``` ... this(R_xlen_t n) { SEXPTYPE _real_ = SEXPTYPE.REALSXP; _data = protect(allocVector(_real_, n)); unprotect(1); } ... ``` Looking at that code, I realise didn't need the un/protect. Actually it's more complicated than that. On construction I do need to call `protect` and call `unprotect` or `unprotect_ptr` when the function in which the object is created returns. At the moment, I'm not even sure (or more likely do not think) that it is suitable to call it as part of the destructor. Anyway, that's an aside.
Re: Can we use "ImportC" used yet?
On Thursday, 21 October 2021 at 23:06:18 UTC, jfondren wrote: On Thursday, 21 October 2021 at 22:23:50 UTC, data pulverizer wrote: I'd first check that the type names look OK in the processed C. If they do, then it's an importc bug. Those are still getting reported, but yours might be new. Worth checking out. I've double-checked and the types names are fine in translated C file. It might also be a bug that's been fixed since release--try dmd master on it. I have the latest compiler installed and I just double-checked by compiling dmd-master with the same result. The specific error is: ``` Error: function `Rf_allocVector(__tag28, long)` is not callable using argument types `(int, long)` cannot pass argument `REALSXP` of type `int` to parameter `__tag28` ``` Here `__tag28` should be `SEXPTYPE` which is an `enum int` containing `REALSXP`. Another (superficial by maybe related) issue is that `REALSXP` is an `SEXPTYPE` which is an `enum int` under the hood but dmd skips the `SEXPTYPE` description altogether, even though SEXPTYPE is correctly converted in the imported C file. Also, with some definitions in the C file, when I try to `#undef` something to get some conditional C definitions to be converted with `gcc -E -P ...`, nothing happens. d doesn't do any C preprocessing, so any problem here is with gcc. Your `#undef`s may be coming before the C preprocessor's own `#define`s and have no effect. I thought I'd ask anyway, it looks like a question for the R community, where `#undef R_NO_REMAP` in the script has no effect. This is unrelated to the first issue. As @Imperatorn said (and I was aware as I asked the question) this is a new feature that is currently being worked on, and we should expect and report stuff like this. It's a great feature and lots of people will use it heavily. Including myself.
Re: function(pointer) as template argument, explicit template instantiation
On Friday, 31 December 2021 at 00:57:26 UTC, kdevel wrote: ```dptr.d class R { } void foo (R r) { } alias fn = void function (R); void lyr (fn F) (R r) { } immutable fn foo_ptr = // line 14 pragma (msg, typeof (foo_ptr)); auto ptr = lyr!(foo_ptr);// line 17 ``` dmd reports: ``` immutable(void function(R)) dptr.d(14): Error: expression `& foo` is not a valid template value argument ``` If I comment out line 17 the code compiles. I want to put the explicitly instantiated function template into an immutable AA. How can that be phrased such that dmd compiles it? Pointers are runtime entities and are not suitable template parameters (compile time). So assuming that you are trying to either pass a function constant of a specific type signature as a template argument, or a function pointer as an argument with either a template specialisation or constraint: ``` class R {} void foo(R r){} alias fn = void function(R); //function compile time constant void lyr(fn fp_type)(R r){} //As template constraint void con(T)(T fun, R r) if(is(T == fn)) { fun(r); } /* //As template specialisation void con(T: fn)(T fun, R r) { fun(r); } */ //Function constant enum fn foo_ptr = (R r){}; pragma(msg, typeof(foo_ptr)); //Declared at compile time but only executable at runtime auto ptr = !(foo_ptr); void main() { //auto ptr = !(foo_ptr);//could declare this here ptr(new R()); fn new_ptr = con(new_ptr, new R()); } ```
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Tuesday, 28 December 2021 at 00:32:03 UTC, Paul Backus wrote: The result of `.stringof` is completely implementation-defined, may change arbitrarily between compiler releases, and is not even guaranteed to be valid D code in the first place. Wow, I didn't know this. In this case, the simplest solution is to have your code generator accept a string as its input, rather than a type. For example: ```d enum instantiate(string type, string expr) = type ~ "(" ~ expr ~ ")"; pragma(msg, instantiate!("RVector!(SEXPTYPE.REALSXP)", "x")); ``` Well the code needs to be responsive from parameter types `T` generated from other code. I'm allowing the user to create functions select those they wish to access in R by UDA decorators in the D script which I then filter for and wrap the necessary functions generating any type conversion code I need at compile time to create functions callable in R.
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Monday, 27 December 2021 at 21:31:03 UTC, Adam Ruppe wrote: if you can paste teh code where you generate this I can prolly show you a much easier way to do it. stringof sucks really hard. Will the above `mixin` example suffice? It expands to the code that I described.
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Monday, 27 December 2021 at 22:52:58 UTC, data pulverizer wrote: I think the only thing to do for now is probably for me to construct a template that creates a proper string for this type. It would look something like this: ``` enum safe_stringof(T) = T.stringof; template safe_stringof(T: MyType!U, alias U) { enum string safe_stringof = "MyType!(" ~ U.stringof ~ ")"; } ``` So this ``` alias DOUBLE = MyEnum.DOUBLE; alias STRING = MyEnum.STRING; alias INTEGER = MyEnum.INTEGER; void main() { alias T = MyType!(INTEGER); alias U = MyType!(STRING); enum code = "writeln(\"instance: \", adder(" ~ safe_stringof!(T) ~ "(), " ~ safe_stringof!(U) ~ "()" ~ "));"; pragma(msg, code); } ``` Which works. Now back to my very late dinner.
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Monday, 27 December 2021 at 21:05:51 UTC, data pulverizer wrote: Hello, ... ... an equivalent mixin error would be ``` //... alias DOUBLE = MyEnum.DOUBLE; alias STRING = MyEnum.STRING; alias INTEGER = MyEnum.INTEGER; void main() { alias T = MyType!(INTEGER); alias U = MyType!(STRING); enum code = "writeln(\"instance: \", adder(" ~ T.stringof ~ "(), " ~ U.stringof ~ "()" ~ "));"; mixin(code); } ```
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Tuesday, 28 December 2021 at 00:57:27 UTC, Paul Backus wrote: ```d enum instantiate(string type, string expr) = type ~ "(" ~ expr ~ ")"; pragma(msg, instantiate!("RVector!(SEXPTYPE.REALSXP)", "x")); ``` One possibility is to generate a collection of compile time strings that denote the types and then to a comparison with the type something like `is(T == mixin(CString)`, where `CString = "RVector!(SEXPTYPE.REALSXP)"` to discover the correct string which I can then use to generate the code without having to use `T.stringof` anywhere in the code at all.
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Monday, 27 December 2021 at 21:31:03 UTC, Adam Ruppe wrote: if you can paste teh code where you generate this I can prolly show you a much easier way to do it. stringof sucks really hard. I think the only thing to do for now is probably for me to construct a template that creates a proper string for this type.
Re: Ambiguity issue with expanding and evaluating single template type parameter enums
On Monday, 27 December 2021 at 23:04:40 UTC, Adam Ruppe wrote: On Monday, 27 December 2021 at 21:21:30 UTC, data pulverizer wrote: alias T = MyType!(INTEGER); What is MyType? enum code = "writeln(\"instance: \", adder(" ~ T.stringof ~ "(), " ~ U.stringof ~ "()" ~ "));"; And why is this a string mixin instead of a plain simple function? prolly need more context Sorry the example is a bit contrived but basically I'm generating a whole bunch of code using string mixins. The types I'm generating are a template type I've constructed for R's SEXP, so that my wrapped numeric vector (struct) type is denoted `RVector!(REALSXP)`. But `alias REALSXP = SEXPTYPE.REALSXP` where `SEXPTYPE` is an `enum`. So if I start using `T.stringof` where `T = RVector!(SEXPTYPE.REALSXP)` to generate code it starts to create chaos because `T.stringof = "RVector!SEXPTYPE.REALSXP"`, so if I'm trying to convert or instantiate a type using `T.stringof ~ "(x)"`, I'll get `RVector!SEXPTYPE.REALSXP(x)` which gives an error, and various types like this can occur many times in a script. The new template allows me to safely paste the type and get what I want `RVector!(SEXPTYPE.REALSXP)(x)`. There are various requirements, sometimes I have to cast or type convert, so I **need** the type to paste correctly and explicitly. Which is what the `safe_stringof` template does for my baby example - the same methodology will work just as well for my `RVector` code.
Ambiguity issue with expanding and evaluating single template type parameter enums
Hello, I'm generating code using mixins and one of my mixins expands to something like this: ``` adder(MyType!MyEnum.INTEGER(), MyType!MyEnum.STRING()); ``` `MyType!MyEnum.STRING` is generated with `T.stringof `. I get the error: ``` Error: template instance `MyType!(MyEnum)` does not match template declaration `MyType(MyEnum type) ``` and if I manually amend the code to this: ``` adder(MyType!(MyEnum.INTEGER)(), MyType!(MyEnum.STRING)()); ``` It runs fine. It looks like the ambiguity of UFCS and type is messing things up. This is a simplified example. Since the code is being generated automatically in many places I can't go round adding the brackets. A simplified functional example is given below: ``` import std.stdio: writeln; enum MyEnum { DOUBLE = 0, STRING = 1, INTEGER = 2 } struct MyType(MyEnum type) {} auto getValue(T: MyType!U, alias U)(T x) { return U; } auto adder(T, U)(T x, U y) { return getValue(x) + getValue(y); } void main() { writeln("instance: ", adder(MyType!MyEnum.INTEGER(), MyType!MyEnum.STRING())); } ```
Re: Double bracket "{{" for scoping static foreach is no longer part of D
On Wednesday, 22 December 2021 at 16:01:49 UTC, rikki cattermole wrote: Seems to be working just fine as of 2.098. ```d import std; void main() { static foreach(Foo; ["Abc", "def"]) {{ string str = Foo; writeln("Hello D ", str, __VERSION__); }} } ``` ``` Hello D Abc2098 Hello D def2098 ``` I see, It looks like I remembered incorrectly about using `{{` in templates! It seems that it doesn't work in templates or in "global" (outside main), so for instance neither this ``` // compiled with -o- flag static foreach(Foo; ["Abc", "def"]) {{ enum str = Foo; pragma(msg, "Hello D ", str, __VERSION__); }} ``` nor this ``` template Demo() { static foreach(Foo; ["Abc", "def"]) {{ enum str = Foo; pragma(msg, "Demo: Hello D ", str, __VERSION__); }} enum Demo = null; } void main() { Demo!() } ``` will run. It gives an error `Error: declaration expected, not {`.
Re: Double bracket "{{" for scoping static foreach is no longer part of D
On Wednesday, 22 December 2021 at 16:10:42 UTC, Adam D Ruppe wrote: So OUTSIDE a function, static foreach() {{ }} is illegal because a plain {} is illegal outside a function. But INSIDE a function, static foreach() {{ }} is legal, but it isn't magic about static foreach - it is just a body with its optional {} present as well as a scope statement inside. Just seen this. Thanks - I should have been more patient.
Double bracket "{{" for scoping static foreach is no longer part of D
Hi All, I noticed that the double bracket `{{` for scoping `static foreach` is no longer part of D and it looks like it has been replaced with https://dlang.org/changelog/2.098.0.html#AliasAssign. Could someone confirm this with a link to the DIP and any other tools that we should be using (I guess it's now more reliance on CTFE)? I tend to avoid CTFE for small amounts of meta-programming since it is resolved at "soft compile time" and being cautious by nature I tend to rely more on templates. The change is not a big deal, I just didn't see any news about it. Many thanks
Bitfileds Error: no identifier for declarator
Hi, I am trying to compile the following items: ``` import std.bitmanip: bitfields; enum TYPE_BITS = 5; enum NAMED_BITS = 16; struct sxpinfo_struct { mixin(bitfields!( SEXPTYPE, "type", TYPE_BITS, uint, "scalar", 1, uint, "obj", 1, uint, "alt", 1, uint, "gp", 16, uint, "mark", 1, uint, "debug",1, uint, "trace",1, uint, "spare",1, uint, "gcgen", 1, uint, "gccls", 3, uint, "named", NAMED_BITS, uint, "extra", 32 - NAMED_BITS)); } ``` But I get the error: ``` Error: no identifier for declarator `uint` Error: identifier or integer expected inside `debug(...)`, not `)` Error: found `@` when expecting `)` Error: no identifier for declarator `safe` Error: declaration expected, not `return` Error: no identifier for declarator `void` Error: identifier or integer expected inside `debug(...)`, not `uint` Error: found `v` when expecting `)` Error: declaration expected, not `)` Error: declaration expected, not `assert` Error: basic type expected, not `cast` Error: found `cast` when expecting `;` Error: declaration expected, not `(` ``` All referencing the `bitfields` `mixin`, more specifically the last two lines but I think it's actually referencing the expanded `mixin` rather than my declaration. Thanks
Re: Bitfileds Error: no identifier for declarator
On Thursday, 28 October 2021 at 05:51:27 UTC, Imperatorn wrote: Try renaming debug to something else Many thanks guys. I should have spotted that one!
Re: Bitfileds Error: no identifier for declarator
On Thursday, 28 October 2021 at 05:20:35 UTC, data pulverizer wrote: Hi, I am trying to compile the following items ... Sorry forgot to prepend: ``` enum SEXPTYPE { NILSXP = 0, SYMSXP = 1, LISTSXP = 2, CLOSXP = 3, ENVSXP = 4, PROMSXP = 5, LANGSXP = 6, SPECIALSXP = 7, BUILTINSXP = 8, CHARSXP = 9, LGLSXP = 10, INTSXP = 13, REALSXP = 14, CPLXSXP = 15, STRSXP = 16, DOTSXP = 17, ANYSXP = 18, VECSXP = 19, EXPRSXP = 20, BCODESXP = 21, EXTPTRSXP = 22, WEAKREFSXP = 23, RAWSXP = 24, S4SXP = 25, NEWSXP = 30, FREESXP = 31, FUNSXP = 99 } ``` In case someone is trying to replicate the error.
Re: Can we use "ImportC" used yet?
On Saturday, 23 October 2021 at 16:39:08 UTC, data pulverizer wrote: ``` ... this(R_xlen_t n) { SEXPTYPE _real_ = SEXPTYPE.REALSXP; _data = protect(allocVector(_real_, n)); unprotect(1); } ... ``` Looking at that code, I realise didn't need the un/protect.
Re: How to return a reference to structs?
Hi, It looks to me like `A*[]` would require extra allocation of memory and `ref` would not, am I wrong? If so it may be something to consider if relevant for your application. Thanks.
Re: The type inference everywhere
On Sunday, 31 October 2021 at 18:51:09 UTC, user1234 wrote: To me it is the right answer. Maybe that OP wanted the TemplateType parameter to be implicitly added (and that's why Ali interpreted the question as a language proposal)? Ah, I see. Interesting proposal.
Re: The type inference everywhere
On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote: On 10/31/21 7:07 AM, Salih Dincer wrote: > ```d > auto foo(int value, auto s = Section(2, 60)) { > int max; /* ^--- ? > ...*/ > return Section (0, max) > } > ``` > Is possible something like above pointed. OK, I know it isn't because I > tried! Well, wouldn't it be nice if it did? Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali This is a teachable moment for me, so I'll ask the question. Why isn't something like this the answer? ``` import std.stdio: writeln; struct Section { int x; int y; } auto foo(T)(int value, auto ref T s = Section(2, 60)) { //... return Section(0, 60); } void main() { foo(5).writeln; } ```
Re: Can we use "ImportC" used yet?
On Friday, 22 October 2021 at 16:16:22 UTC, Dave P. wrote: I think you ran into this [issue](https://issues.dlang.org/show_bug.cgi?id=22404). The bug fix isn’t part of a released dmd yet. Yes that's the same error. When I try this: ``` ... this(R_xlen_t n) { SEXPTYPE _real_ = SEXPTYPE.REALSXP; _data = protect(allocVector(_real_, n)); unprotect(1); } ... ``` I get a slightly more interesting error message: ``` types.d(43): Error: cannot implicitly convert expression `14` of type `int` to `__tag28` ``` So it's not recognising `REALSXP` as an `SEXPTYPE`, it's as if it is treating `SEXPTYPE` like a `struct` rather than an `enum`. Also I was wandering, how long will it take release a fix for ImportC? I am aware that it is a new feature, the reason I ask is not to try to rush anyone but to plan my time better. Many thanks
Setting SQLite compile time parameters from etc.c.sqlite3
Hello all, I'm not sure how to set the compile time parameters in D's SQLite module particular the items that take multiple parameters, for example in the C API manual `SQLITE_CONFIG_MMAP_SIZE` takes two `sqlite3_int64`. How do I set these? Do I just write something like ``` enum SQLITE_CONFIG_MMAP_SIZE = [10_000_000_000, 30_000_000_000]; ``` ? Writing this doesn't cause an error but I don't think it works because its supposed to speed up write times and I'm not observing any performance change. Thanks in advance!
Re: Setting SQLite compile time parameters from etc.c.sqlite3
On Tuesday, 1 March 2022 at 20:59:46 UTC, data pulverizer wrote: Hello all, I'm not sure how to set the compile time parameters in D's SQLite module particular the items that take multiple parameters, for example in the C API manual `SQLITE_CONFIG_MMAP_SIZE` takes two `sqlite3_int64`. How do I set these? Okay it seems like you are supposed to use the function `sqlite3_config` to configure those elements, for example: ``` sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, 10_000_000_000, 30_000_000_000); ```
Re: dub import local D package
On Thursday, 21 April 2022 at 03:59:26 UTC, Steven Schveighoffer wrote: OK, so reviewing with that in mind, it looks like you're trying to import `myPackage.modules.mymodule`, but the file `../myPackageName/source/myPackageName/modules/mymodule.d` doesn't exist. Is there one too many "myPackageName" packages here? Yes, looks like that it works if I change to `import modules.mymodule;`.
Re: dub import local D package
On Thursday, 21 April 2022 at 00:14:16 UTC, Steven Schveighoffer wrote: Did you substitute something real with `...` to hide it from your post? Because that's not a real path. I used it to hide my actual paths.
dub import local D package
Hi all, I'm trying to import a local dub package into a dub project (`json` format). I have added the package I'm trying to import with `dub add-local` and `dub add-path` and including it within the json file, but I get the error ``` $ dub build Performing "debug" build using /.../ldc2/bin/ldc2 for x86_64. myPackageName 0.1.0: target for configuration "library" is up to date. test ~master: building configuration "application"... source/app.d(1,8): Error: module `mymodule` is in file 'myPackageName/modules/mymodule.d' which cannot be read import path[0] = source/ import path[1] = ../myPackageName/source/ import path[2] = /.../ldc2/bin/../import /.../ldc2/bin/ldc2 failed with exit code 1. ``` The dependencies in the dub.json file looks like this: ``` "dependencies": { "myPackageName": { "path": "/.../myPackageName", "version": "0.1.0" } } ``` Thanks in advance
Catching C errors
Hi all, I am calling code from a C API, and would like to know how to catch exit errors so that they can be handled and make them more like an exceptions so that the computation can continue. I've tried something similar to what is outlined here: https://dlang.org/phobos/object.html#.Error but it doesn't work, the process dies in the try block. Thanks
Re: Catching C errors
On Wednesday, 19 October 2022 at 14:05:35 UTC, data pulverizer wrote: Hi all, I am calling code from a C API, and would like to know how to catch exit errors so that they can be handled and make them more like an exceptions so that the computation can continue. I've tried something similar to what is outlined here: https://dlang.org/phobos/object.html#.Error but it doesn't work, the process dies in the try block. Thanks It's okay, I've found a work around.
Re: Catching C errors
On Thursday, 20 October 2022 at 13:02:52 UTC, bachmeier wrote: I've done an initial release of the second version: https://github.com/bachmeil/embedrv2 The two biggest changes are - Moving to Dub as the default for compilation, which allows the use of any other Dub libraries - It writes the wrappers for you. You write a D function and it converts it to R. The part I haven't finished is in the other direction. For instance, suppose you have a D function that sends data to R many times. If you don't release the memory on the R side, your program's going to crash quickly. I haven't worked on this recently because I've mostly been calling D functions from R. Haven't see this update, good to know!
Re: Catching C errors
On Thursday, 20 October 2022 at 10:13:41 UTC, Sergey wrote: On Thursday, 20 October 2022 at 09:52:05 UTC, data pulverizer wrote: I'm currently writing a D interop with R, the dynamic statistical programming language. There's a function called How is your project related to EmbedR? The description of the project could be found here: https://dlang.org/blog/2020/01/27/d-for-data-science-calling-r-from-d/ AFAIK Lance wants to re-write it to the second version with some improvements in the code. I know about the EmbedR project. I'm doing a "full-throated" R<->D API aiming to be on the scale of Rcpp (https://cran.r-project.org/web/packages/Rcpp/index.html) all built with native D code, which is more full-featured than EmbedR - which ships with a DLL that some end users will probably not accept and does not have the full capability and convenience of something like Rcpp. The architecture of my library and my approach is also quite different to EmbedR. I also have structures like `alias NumericVector = RVector!(SEXPTYPE);` and so on, which builds in all the D-lang ops, and so on to allow a full interop with the R API. Mine is also private for now till it reaches an acceptable state when I'll think about whether it should be publicly released or jealously guarded. It's a project I'm building for my own use really.
Re: Catching C errors
On Wednesday, 19 October 2022 at 16:48:10 UTC, Ali Çehreli wrote: On 10/19/22 07:05, data pulverizer wrote: > I am calling code from a C API, and would like to know how to catch exit > errors If you are talking about the exit() Posix function, you can't do anything about that because its purpose is to cause "normal process termination". Ali Yes it is the `exit()` function in the end I figured that it couldn't be sidestepped like an exception so I did something else. As it happens, the situation turned out to be a bit trivial, not even sure if it's worth going into. But for those interested the description is below. I'm currently writing a D interop with R, the dynamic statistical programming language. There's a function called `Rf_initEmbeddedR()` which allows you to call the full R C API from D without having to compile a DLL and call code from R. There is also a function called `Rf_endEmbeddedR(int fatal)`, which I assumed terminates the R session, but it doesn't, after seeing the code it only cleans some things up and looks as if it is intended to be used just before you exit main. I have unit tests in D that begin with the init function and finish with the end function, and when I tried re-initialising I get an exit() error saying the R session was already initialized. So all I did was create a static init flag, and a wrapper function to only call init if the flag is false. As I said in the end it was trivial.
Re: Catching C errors
On Thursday, 20 October 2022 at 12:14:38 UTC, jmh530 wrote: On Thursday, 20 October 2022 at 11:59:45 UTC, data pulverizer wrote: [snip] Mine is also private for now till it reaches an acceptable state when I'll think about whether it should be publicly released or jealously guarded. It's a project I'm building for my own use really. It can't hurt to publicly release (when ready) so that other users work through any kinks. Those are good points. I'll give it some thought when the time comes. Thanks!
Re: Stop writeln from calling object destructor
On Monday, 3 October 2022 at 11:08:00 UTC, Steven Schveighoffer wrote: On 10/2/22 12:21 PM, data pulverizer wrote: I've noticed that `writeln` calls the destructor of a struct multiple times and would like to know how to stop this from happening. It has become a very serious problem when working with objects that have memory management external to D. I know you already solved the problem, but just for future reference, if you use something like `RefCounted`, you can avoid copying and destruction until everyone is done with the object. This is how my io library works, the IO objects are non-copyable, and you wrap them in `RefCounted` if you want to copy them. -Steve Just seen this. Nice one. The docs link: https://dlang.org/library/std/typecons/ref_counted.html
Re: Stop writeln from calling object destructor
On Sunday, 2 October 2022 at 16:44:25 UTC, Paul Backus wrote: It's because `writeln` is copying the object, and each of the copies is being destroyed. If you add a copy constructor to your example, you can see it happening: ... I thought something like this could be happening in my original implementation and tried implementing a copy constructor using this reference https://dlang.org/spec/struct.html#struct-copy-constructor but it did not work. Both your's and the manual's suggestion works for my baby example but not for my actual code. Any reason why this could be?
Re: Stop writeln from calling object destructor
On Sunday, 2 October 2022 at 17:19:55 UTC, data pulverizer wrote: Any reason why this could be? Sorry I'll need to implement all the overloaded copy constructors and see if that fixes it.
Re: Stop writeln from calling object destructor
On Sunday, 2 October 2022 at 17:51:59 UTC, Ali Çehreli wrote: What I noticed first in your original code was that it would be considered buggy because it was not considering copying. Every struct that does something in its destructor should either have post-blit (or copy constructor) defined or simpler, disallow copying altogether. Thanks for the advice, for a while now I didn't know what was creating the issue. The code I'm running is my D connector to the R API and for ages I didn't know where the multiple destructor calls to allow an object to be garbage collected by the R API was coming from, and it was breaking the whole thing. I think I'll have to play it by ear whether to disable the copy constructor altogether or to use it now it is working. Thanks both of you.
Re: Stop writeln from calling object destructor
On Sunday, 2 October 2022 at 18:24:51 UTC, Ali Çehreli wrote: I've just tested. That is used only for explicit constructor syntax ... Many thanks. Knowledgeable as always!
Re: Stop writeln from calling object destructor
On Sunday, 2 October 2022 at 17:28:51 UTC, data pulverizer wrote: Sorry I'll need to implement all the overloaded copy constructors and see if that fixes it. I've got it, something weird happened to my copy constructor. This was my original attempt and was ignored (didn't run in the copy constructor): ``` this(T)(ref return scope T original) if(is(T == RVector!(Type))) { //... code ... } ``` But this now works: ``` this(ref return scope RVector!(Type) original) { //... code ... } ``` No idea why. `Type` is a template parameter of the object.
Stop writeln from calling object destructor
I've noticed that `writeln` calls the destructor of a struct multiple times and would like to know how to stop this from happening. It has become a very serious problem when working with objects that have memory management external to D. Here is a repeatable example, where the destructor appears to have been called 4 times with one call of `writeln` before the object actually goes out of scope: Code: ``` import std.stdio: writeln; struct MyObject { int id; this(int id) @nogc { this.id = id; } ~this() { writeln("Object destructor ..."); } } void main() { auto obj = MyObject(42); writeln("MyObject: ", obj); writeln("Goodbye:\n"); } ``` Output: ``` $ rdmd gc.d MyObject: MyObject(42)Object destructor ... Object destructor ... Object destructor ... Object destructor ... Goodbye: Object destructor ... ``` Thank you