Re: Release D 2.090.0
I have just added workaround of this bug in by code. And now it is working and returns backtrace string[] getBacktrace(Throwable ex) { import std.conv: to; import core.exception: OutOfMemoryError; string[] backTrace; try { foreach( inf; ex.info ) backTrace ~= inf.to!string; } catch( OutOfMemoryError exc ) {} // Workaround for some bug in DefaultTraceInfo.opApply return backTrace; } auto errorToJSON(Throwable ex) { import std.json: JSONValue; return JSONValue([ "code": JSONValue(1), "message": JSONValue(ex.msg), "data": JSONValue([ "file": JSONValue(ex.file), "line": JSONValue(ex.line), "backtrace": JSONValue(getBacktrace(ex)) ]) ]); }
Re: DIP 1027---String Interpolation---Format Assessment
On 2/28/20 7:57 PM, aliak wrote: I actually didn't realize it was a video, thought it was just an article! - But anyway, it was just to point out that swift lowers to specialized types when it comes to interpolation (which is what you and adam are trying to get through). And therefor you can detect interpolations being given to you and deal with them the way you want and you can do a lot when you know you're getting an interpolation. You can create types like let example: SQLStatment = "select * from blah where a=\(a), b=\(b) ... " I didn't get to this part of the video, but that is indeed pretty cool. I'm assuming that this generates placeholders for the SQL statement and attaches a and b as parameters? However, D cannot do something like this exactly, because expressions define the tuple, not how they are used. But this is possible (with the proposed DIP or ours): alias sql = "select * from blah where a=$a, b=$b"; // aliased to the tuple connection.query(sql); a = 5; connection.query(sql); // another query with `a` set to 5 now. Swift can do some pretty cool things due to the type resolver, but it comes at a cost (some expressions that are trivial in D make the compiler complain about them taking too long to resolve). I also didn't realize the takeaway would be that swift does appending - which by the way, is not completely accurate. And it does not generate temporaries (unless you mean passing in parameters? There's no way around that if you want to end up with a string based on runtime values - it'll have to be processed in to a string somewhere). For example, the part where they change the date formatting, they use a date formatter to generate a string for the date, which then is appended to the string interpolation. Yes, you need to allocate a string. But you should only allocate one. You can also get an interpolated string directly in to "print processing" if you wanted to: https://swift.godbolt.org/z/muAzgm Hm... I'm not too impressed with this when compared to writefln(i"hello $("hello"), $x"); which works without such extra mechanics or strange call syntax. When it comes to printing it really doesn't matter if you construct a string on the stack and pass it along. You're IO bound anyway. IO is not usually processed directly to the device. Usually it's buffered. Writing directly to the buffer is preferable to generating a string on the stack, and just copying that to the buffer. One very interesting thing of note is the way they combine named arguments with string interpolations. Yeah, that part is cool. But that comes for free with Swift. Potentially with the right additions to the named parameters DIP, it would be feasible to do something similar with this DIP. Also another note, this tuple expansion should really not be called string interpolation, since it does not result in a string :/ It's more string expansion really. I recommended calling it a "formatted tuple" to avoid conflation with existing string interpolation implementations. -Steve
Re: The Serpent Game Framework - Open Source!!
On Saturday, 29 February 2020 at 07:18:26 UTC, aberba wrote: On Thursday, 27 February 2020 at 22:29:41 UTC, aberba wrote: There's this ongoing open source game framework by Ikey. I knew him to be a diehard C guru (from the Solus Project) but is now rocking D, hence Serpent. [...] Ikey did an interview with Foss and he said something about why he uses D. It's interested and funny as well. Having done a lot of Go development, I started researching alternatives to C that were concurrency-aware, string-sane, and packed with a powerful cross-platform standard library. This is the part where everyone will automatically tell you to use Rust. Unfortunately, I’m too stupid to use Rust because the syntax literally offends my eyes. I don’t get it, and I never will. Rust is a fantastic language and as academic endeavours go, highly successful. Unfortunately, I’m too practically minded and seek comfort in C-style languages, having lived in that world too long. So, D was the best candidate to tick all the boxes, whilst having C & C++ interoptability. Pew! Pew!! Nailed it. https://itsfoss.com/ikey-doherty-serpent-interview/ from the article Unfortunately, I’m too stupid to use Rust because the syntax literally offends my eyes. I don’t get it, and I never will. Rust is a fantastic language and as academic endeavours go, highly successful. Unfortunately, I’m too practically minded and seek comfort in C-style languages, having lived in that world too long. So, D was the best candidate to tick all the boxes, whilst having C & C++ interoptability. That's exactly my sentiment too.
Re: Release D 2.090.0
I believe that problemme is somehow connected with core.runtime.DefaultTraceInfo. I figured out that it fail inside a function that tries to get trace info for exception. Body is pretty simple. I created the case where `ex` is just an instance of standart Exception class in order to eliminate some side effects or errors that could be introduced by my code. auto errorToJSON(Throwable ex) { import std.json: JSONValue; import std.conv: to; string[] backTrace; // Commenting this loop removes memory error foreach( inf; ex.info ) backTrace ~= inf.to!string; // Debug point is there JSONValue jErr = [ "code": JSONValue(1), "message": JSONValue(ex.msg), "data": JSONValue([ "file": JSONValue(ex.file), "line": JSONValue(ex.line), "backtrace": JSONValue(backTrace) ]) ]; return jErr; } I just tried to debug this code. And put debug point there (where it is commented). And programme fails after several iterations in this loop. There is call stack at this break point: webtank.net.utils.errorToJSON(object.Throwable).__foreachbody2(ref const(char[]))@0x55d35317 (/home/uranuz/sources/webtank/src/webtank/net/utils.d:112) _D4core7runtime16DefaultTraceInfo7opApplyMxFMDFKxAaZiZ__T9__lambda2TmZQnMFKmKxQBdZi@0x55e1a4ac (Unknown Source:0) rt.backtrace.dwarf.traceHandlerOpApplyImpl(const(void*[]), scope int(ref ulong, ref const(char[])) delegate)@0x55e1c65c (Unknown Source:0) core.runtime.DefaultTraceInfo.opApply(scope int(ref ulong, ref const(char[])) delegate) const@0x55e1a501 (Unknown Source:0) core.runtime.DefaultTraceInfo.opApply(scope int(ref const(char[])) delegate) const@0x55e1a47e (Unknown Source:0) webtank.net.utils.errorToJSON(object.Throwable)@0x55d34fa6 (/home/uranuz/sources/webtank/src/webtank/net/utils.d:111) _D7webtank3net6server6common17makeErrorResponseFC6object9ThrowableCQCnQCi4http6output10HTTPOutputZv@0x55d349bb (/home/uranuz/sources/webtank/src/webtank/net/server/common.d:50) _D7webtank3net6server6common14processRequestFC3std6socket6SocketCQClQCgQCf5iface10IWebServerZv@0x55d16f96 (/home/uranuz/sources/webtank/src/webtank/net/server/common.d:113) _D3std11parallelism__T3runTPFCQBc6socket6SocketC7webtank3net6server5iface10IWebServerZvTQChTCQBtQBoQBn11thread_pool16ThreadPoolServerZQEiFQEhKQEjKQCcZv@0x55cc27cf (/usr/include/dmd/phobos/std/parallelism.d:761) _D3std11parallelism__T4TaskSQBaQz3runTPFCQBn6socket6SocketC7webtank3net6server5iface10IWebServerZvTQChTCQBtQBoQBn11thread_pool16ThreadPoolServerZQEt4implFPvZv@0x55cc2171 (/usr/include/dmd/phobos/std/parallelism.d:444) std.parallelism.AbstractTask.job()@0x55dbb423 (Unknown Source:0) _D3std11parallelism8TaskPool5doJobMFPSQBkQBj12AbstractTaskZv@0x55dbb574 (Unknown Source:0) std.parallelism.TaskPool.executeWorkLoop()@0x55dbb6ea (Unknown Source:0) std.parallelism.TaskPool.startWorkLoop()@0x55dbb690 (Unknown Source:0) core.thread.osthread.Thread.run()@0x55da74de (Unknown Source:0) thread_entryPoint@0x55de9016 (Unknown Source:0) start_thread@0x772176db (/build/glibc-OTsEL5/glibc-2.27/nptl/pthread_create.c:463) clone@0x7657e88f (/build/glibc-OTsEL5/glibc-2.27/sysdeps/unix/sysv/linux/x86_64/clone.S:95) So I believe that bug is somewhere around there. Because there are some fixed size buffers in code. And have some template code, so symbol names could be greather in size that this buffers. And this case could be not handled good enough. What dou you think about it? I shall try to create some representative example of smaller size to fill a bug report.