Re: What are (were) the most difficult parts of D?
On Saturday, 14 May 2022 at 04:31:48 UTC, zjh wrote: Likewise, each post could add something like `votes` , Or something like all kinds of `tags` such as `range/fiber/commandline/auto ref/in/...`. Making `good use` of the `existing answers` in the forum will be very beneficial for `D` beginners. Moreover, `excellent d expert` do not have to repeat `previous answers`, and just provide a link.
Re: What are (were) the most difficult parts of D?
On Saturday, 14 May 2022 at 04:09:00 UTC, Ali Çehreli wrote: stopped by a spam filter. Right. D forum should add a "`author delete`" function. Likewise, each post could add something like `votes` , good posts will naturally `come out` and be collected together. It's really convenient for beginners of `d`. This way, the similar answer does not have to be repeated.
Re: What are (were) the most difficult parts of D?
On 5/13/22 21:07, zjh wrote: On Friday, 13 May 2022 at 21:54:04 UTC, max haughton wrote: Can `D` support error messages in `multiple languages`? Such as `Chinese/German/Russian/Turkey`. OT: It is unlikely but possible that posts are sometimes stopped by a spam filter. That must be why zjh tried to post this a second time. Ali
Re: What are (were) the most difficult parts of D?
On Friday, 13 May 2022 at 21:54:04 UTC, max haughton wrote: Can `D` support error messages in `multiple languages`? Such as `Chinese/German/Russian/Turkey`.
Re: What are (were) the most difficult parts of D?
On Friday, 13 May 2022 at 21:54:04 UTC, max haughton wrote: I have a PR which alters the error message you get if you do ```d void main() { func() == 43; } ``` This is an example of an error message which could be counterintuitive to a new D programmer, Can `D` support error messages in `multiple languages`? Such as `Chinese/German/Russian/Turkey`.
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 13:06:32 UTC, vit wrote: On Friday, 13 May 2022 at 11:58:15 UTC, zjh wrote: Thank you for your detail explain.
Re: Back to Basics at DConf?
On Friday, 13 May 2022 at 15:56:31 UTC, H. S. Teoh wrote: My mental image of this is Ali presenting some simple common task, then at 3/4 of the presentation there's an amazing trick that lets you write it in D in 5 times less code than in other languages, and my mind is blown and I remember why I love D so much. :-P T perhaps someone should start a D version of this: https://github.com/ruppysuppy/Daily-Coding-Problem-Solutions
Re: What are (were) the most difficult parts of D?
On Friday, 13 May 2022 at 19:16:59 UTC, Steven Schveighoffer wrote: But we also have this confusing dynamic: |scope |no attribute| shared |static | ||||---| |module |TLS |global |TLS (no-op)| |function|local |local! |TLS| |class |instance|global |TLS| There is a typo in your array, a shared field is per-instance, not global. class A { shared int c; // Each A has its own c }
Re: What are (were) the most difficult parts of D?
On Friday, 13 May 2022 at 21:07:12 UTC, Christopher Katko wrote: Is there any way we can get numbered errors like C++ / Microsoft have? E2040 Declaration terminated incorrectly Because then we could easily have a wiki for common error cases with code snippets of it occurring, and a fix for it. Common triggers of this error vs the proper code. And a neat feature that Allegro.cc does, it automatically scans forum posts for usages of Allegro functions (e.g. al_draw_bitmap() man page will include links to posts that ask about al_draw_bitmap and has a Yes/No question next to it "was this a helpful post" so you can remove bad matches). Here it would be even easier than matching random questions because error codes are specific string literals ("E2040") and not some sort of regex attempt to match someone asking a question about 'R[][][] datatypes' or something like that. Here is an example: https://www.allegro.cc/manual/5/al_draw_bitmap and an C++ error page: https://docwiki.embarcadero.com/RADStudio/Sydney/en/E2040_Declaration_terminated_incorrectly_(C%2B%2B) We discussed this a while ago in a foundation meeting. The details didn't really get hashed out but I think we can definitely try it. I have a PR which alters the error message you get if you do ```d void main() { func() == 43; } ``` This is an example of an error message which could be counterintuitive to a new D programmer, e.g. maybe they thought it would act like an assert or whatever, so we can link to a some html somewhere on dlang.org
Re: What are (were) the most difficult parts of D?
Is there any way we can get numbered errors like C++ / Microsoft have? E2040 Declaration terminated incorrectly Because then we could easily have a wiki for common error cases with code snippets of it occurring, and a fix for it. Common triggers of this error vs the proper code. And a neat feature that Allegro.cc does, it automatically scans forum posts for usages of Allegro functions (e.g. al_draw_bitmap() man page will include links to posts that ask about al_draw_bitmap and has a Yes/No question next to it "was this a helpful post" so you can remove bad matches). Here it would be even easier than matching random questions because error codes are specific string literals ("E2040") and not some sort of regex attempt to match someone asking a question about 'R[][][] datatypes' or something like that. Here is an example: https://www.allegro.cc/manual/5/al_draw_bitmap and an C++ error page: https://docwiki.embarcadero.com/RADStudio/Sydney/en/E2040_Declaration_terminated_incorrectly_(C%2B%2B)
Re: Error: variable `impl` cannot be modified at compile time
On Friday, 13 May 2022 at 19:48:04 UTC, Steven Schveighoffer wrote: On 5/13/22 3:46 PM, Steven Schveighoffer wrote: What writeln? Your compile trace is missing the original call line, and I would say probably more. Looking at your last commit, I figured it out: https://github.com/kerisy/archttp/blob/545b3eb738261e92c88b4e4bb664b4fdfb206398/source/archttp/codec/HttpDecoder.d#L31 That's where you are attempting to build an HttpRequestParser at compile time. Just use the `__ctfe` trick. -Steve Thank you my friend.
Re: Template shenannigans with multiple datatypes
On 5/13/22 00:32, Chris Katko wrote: > Luckily, because I'm painting them to the screen, the > buffers only really need to be float even if they started as a boolean, > int, or double. However, if I'm keeping a list of pointers to things I > want to snoop when I call onTick(), I can't think of a way to support > multiple types: I think this is a classic example of OOP. You abstract data collection to classes that know how to deal with their own data type. The comments should explain it: import std.algorithm; import std.conv; import std.range; import std.random; import std.stdio; interface DataSource { // Represents "reporting" of data points to the graph. float[] dataPoints(); // Represents a collection of data. void collect(); } // A templatized implementation of DataSource that would // work with fundamental types like 'int'. class SimpleDataSource(T) : DataSource { T[] data;// All collected data size_t next; // The beginning of data for next dataPoints() // Converts data to float[], the uniform representation. float[] dataPoints() { auto result = data[next..$].map!(to!float).array; next = data.length; return result; } void collect() { // Random number of random values const n = uniform(3, 10); iota(n).each!(i => data ~= uniform(10, 20)); } } // Converted to a 'struct'. Could stay 'class'. struct intrinsicGraph { DataSource[] dataSources; // Same type collectors float[] buffer;// Same type data void onTick() { // Go through all sources to update 'buffer'. dataSources.each!(source => buffer ~= source.dataPoints()); } } void main() { // Independent collectors. auto source1 = new SimpleDataSource!int(); auto source2 = new SimpleDataSource!double(); auto g = intrinsicGraph(); // This part is the "registration" of data sources, // which could be like g.register(source1). g.dataSources ~= source1; g.dataSources ~= source2; // Represents a time slice. foreach (i; 0 .. 3) { source1.collect(); source2.collect(); g.onTick(); } // It works! :) writeln(g.buffer); } Ali
Re: Error: variable `impl` cannot be modified at compile time
On 5/13/22 3:46 PM, Steven Schveighoffer wrote: What writeln? Your compile trace is missing the original call line, and I would say probably more. Looking at your last commit, I figured it out: https://github.com/kerisy/archttp/blob/545b3eb738261e92c88b4e4bb664b4fdfb206398/source/archttp/codec/HttpDecoder.d#L31 That's where you are attempting to build an HttpRequestParser at compile time. Just use the `__ctfe` trick. -Steve
Re: Error: variable `impl` cannot be modified at compile time
On 5/13/22 3:39 PM, zoujiaqing wrote: ```bash % git clone https://github.com/kerisy/archttp.git % cd archttp/ % dub build --compiler=dmd Performing "debug" build using dmd for x86_64. archttp 0.0.1+commit.3.g70d44ef: building configuration "library"... ../../.dub/packages/nbuff-0.1.14/nbuff/source/nbuff/buffer.d(74,25): Deprecation: `catch` statement without an exception specification is deprecated ../../.dub/packages/nbuff-0.1.14/nbuff/source/nbuff/buffer.d(74,25): use `catch(Throwable)` for old behavior SSE: false /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(5190,5): Error: variable `impl` cannot be modified at compile time /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(4130,12): called from here: `makeGlobal()` /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(4220,18): called from here: `trustedStdout()` ``` Why can't we use writeln in constructors? Comment out writeln so that the code will compile properly! What writeln? Your compile trace is missing the original call line, and I would say probably more. From what you are saying, it appears that you are calling writeln inside a constructor, and you are attempting to build an instance of the object at compile time. Instead of commenting out the writeln, maybe gate it with `if(!__ctfe)`. -Steve
Error: variable `impl` cannot be modified at compile time
```bash % git clone https://github.com/kerisy/archttp.git % cd archttp/ % dub build --compiler=dmd Performing "debug" build using dmd for x86_64. archttp 0.0.1+commit.3.g70d44ef: building configuration "library"... ../../.dub/packages/nbuff-0.1.14/nbuff/source/nbuff/buffer.d(74,25): Deprecation: `catch` statement without an exception specification is deprecated ../../.dub/packages/nbuff-0.1.14/nbuff/source/nbuff/buffer.d(74,25):use `catch(Throwable)` for old behavior SSE: false /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(5190,5): Error: variable `impl` cannot be modified at compile time /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(4130,12): called from here: `makeGlobal()` /opt/dmd/osx/bin/../../src/phobos/std/stdio.d(4220,18): called from here: `trustedStdout()` ``` Why can't we use writeln in constructors? Comment out writeln so that the code will compile properly!
Re: What are (were) the most difficult parts of D?
On 5/13/22 2:29 PM, Adam D Ruppe wrote: On Friday, 13 May 2022 at 18:23:58 UTC, H. S. Teoh wrote: On Thu, May 12, 2022 at 11:45:47PM +, Guillaume Piolat via It's a problem because it goes from solving "no accidental race condition" and you get "people forget to add shared or __gshared and their shared library silently fail" situation. You could have none of that with explicit TLS. Valid point. Yeah, I used to be pro-TLS by default, then got bit by it several times and moved to the fence, and now I'm anti. Data races aren't actually prevented by it (maybe forcing you to specify shared or tls would at least get you think about it though) and lots of things mysteriously fail if you forget about it. I disagree. I'd rather have a program fail in a way that is predictable and explainable than one with memory corruption or race conditions. In fact, I'd rather have 100 TLS confusion failures than one memory corruption failure. Either way you will have failures due to under-specification. Which failures do you choose to debug? Note that with the no shared access update, this will be more obvious of a mistake. This a case where I think forcing explitness would be better than either default Perhaps this would be reasonable. But I find the default reasonable too. But we also have this confusing dynamic: |scope |no attribute| shared |static | ||||---| |module |TLS |global |TLS (no-op)| |function|local |local! |TLS| |class |instance|global |TLS| Honestly, if we changed `static` storage class to `@tls`, and then required it whenever you wanted TLS data, it would be a huge improvement. -Steve
Re: What are (were) the most difficult parts of D?
On Fri, May 13, 2022 at 06:29:54PM +, Adam D Ruppe via Digitalmars-d-learn wrote: [...] > Yeah, I used to be pro-TLS by default, then got bit by it several > times and moved to the fence, and now I'm anti. > > Data races aren't actually prevented by it (maybe forcing you to > specify shared or tls would at least get you think about it though) > and lots of things mysteriously fail if you forget about it. > > You can lock the variable and everything and it still null cuz it was > tls the whole time. Oops. > > This a case where I think forcing explitness would be better than > either default, but failing that, tls by default is the more-bad > choice. Personally I prefer avoiding globals at all. :-P But OK, sometimes you can't work around it (or it'd be too onerous). I guess maybe that's why I haven't been bitten by TLS so far. Hardly ever use it. :-D T -- "Outlook not so good." That magic 8-ball knows everything! I'll ask about Exchange Server next. -- (Stolen from the net)
Re: What are (were) the most difficult parts of D?
On Friday, 13 May 2022 at 18:23:58 UTC, H. S. Teoh wrote: On Thu, May 12, 2022 at 11:45:47PM +, Guillaume Piolat via It's a problem because it goes from solving "no accidental race condition" and you get "people forget to add shared or __gshared and their shared library silently fail" situation. You could have none of that with explicit TLS. Valid point. Yeah, I used to be pro-TLS by default, then got bit by it several times and moved to the fence, and now I'm anti. Data races aren't actually prevented by it (maybe forcing you to specify shared or tls would at least get you think about it though) and lots of things mysteriously fail if you forget about it. You can lock the variable and everything and it still null cuz it was tls the whole time. Oops. This a case where I think forcing explitness would be better than either default, but failing that, tls by default is the more-bad choice.
Re: What are (were) the most difficult parts of D?
On Thu, May 12, 2022 at 11:45:47PM +, Guillaume Piolat via Digitalmars-d-learn wrote: > On Thursday, 12 May 2022 at 17:34:30 UTC, H. S. Teoh wrote: > > > > Why is TLS by default a problem? > > > > It's not really for optimization, AIUI, it's more for thread safety: > > module-global state is TLS by default, so you don't accidentally > > introduce race conditions. > > What you accidentally have instead is people expecting top-level to be > global and instead you get TLS, so it's a surprise. > I mean, a lot of things works like C and C++, but not that. > > It's a problem because it goes from solving "no accidental race > condition" and you get "people forget to add shared or __gshared and > their shared library silently fail" situation. You could have none of > that with explicit TLS. Valid point. > > > - `shared static this()` vs `static this()` is another trap. > > > > One is per-process, one is per-thread. Why is this a trap? > > Well because you can get that wrong. > You get to initialize "__gshared" variables in "shared static this". > It's not hard, but it's something more to explain. I see. [...] > > I wouldn't sweat it if I couldn't easily add `pure` to an entire > > codebase -- it hardly makes any difference anyway. > > If it doesn't make a difference to the bottom-line then why keep it? It's useful in smaller pockets of code. Like factory functions that implicitly cast to immutable, or arithmetic functions whose return values you want to compute only once in a complex expression. It's also useful for maintaining the cleanliness of code (make sure your function doesn't have inadvertent access to global state where you didn't intend it to). But blanket-applying `pure` to an entire codebase? Don't really see the value. For things like I/O it's inherently impure anyway. > > you're on your own and you take responsibility for any problems that > > you may inadvertently introduce by using the escape hatch. > > Well sizeable @afe code has heaps of @trusted code, so the escape > hatch is very routine. IMO, that's a code smell. @trusted should be used as little as possible, only where it's absolutely unavoidable. If there's more than a handful of @trusted in your code, or if you have giant sections of code with `@trusted:` at the top, you're probably doing it wrong. > > it's none of the users' business. > > I'm not disagreeing about @trusted in API. > But I was remarking in practice that @safe would mean different > invariants. it's not a big issue, I was probably ranting. OK, we all rant sometimes. :-) [...] > > So I'm curious, what exactly is it about UFCS chains that make it > > less maintainable? > > Probably personal preference, I mostly write the pedestrian way, so > that debugging/optimization goes faster (maybe wrong, dunno). > > In the dlang.org example: > > void main() > { > stdin > .byLineCopy > .array > .sort!((a, b) => a > b) // descending order > .each!writeln; > } > > This code has a number of prerequisites to be able to read: why is > ".array" needed, why is it ".byLineCopy" vs ".byLine", is the sort > stable, etc. It's just requires more time spent with the language. But doesn't reading (and esp maintaining) *any* code require some time spent with the language anyway? I've worked in enterprise environments long enough to be extremely fearful of coders who parachute into a project and make changes without actually understanding what they're doing ("the code reads that way, I assumed it worked that way"), and then airlift out afterwards leaving the resulting mess to long-time fools like myself to clean up. Maybe it's a bias from working in a primarily C environment where the language is inherently fragile and doesn't protect you from many common human errors, but I'm extremely skeptical of people who expect to just read code and understand it without actually learning the language for real. But OK, I'm just ranting, I'll shut up now. :-D T -- Genius may have its limitations, but stupidity is not thus handicapped. -- Elbert Hubbard
Re: Language server
I have now a language server running for dlang and ocaml on the neovim editor. I'll post here the config init.vim for someone who might be interested. ``` call plug#begin() Plug 'https://github.com/vim-airline/vim-airline.git' Plug 'https://github.com/preservim/nerdtree.git' Plug 'https://github.com/lifepillar/pgsql.vim.git' Plug 'https://github.com/rafi/awesome-vim-colorschemes' " The default plugin directory will be as follows: " - Vim (Linux/macOS): '~/.vim/plugged' " - Vim (Windows): '~/vimfiles/plugged' " - Neovim (Linux/macOS/Windows): stdpath('data') . '/plugged' " You can specify a custom plugin directory by passing it as the argument " - e.g. `call plug#begin('~/.vim/plugged')` " - Avoid using standard Vim directory names like 'plugin' " Make sure you use single quotes " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align Plug 'junegunn/vim-easy-align' " Any valid git URL is allowed Plug 'https://github.com/junegunn/vim-github-dashboard.git' " Multiple Plug commands can be written in a single line using | separators Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' " On-demand loading Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } Plug 'tpope/vim-fireplace', { 'for': 'clojure' } " Using a non-default branch Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) Plug 'fatih/vim-go', { 'tag': '*' } " Plugin options Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } " Plugin outside ~/.vim/plugged with post-update hook Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } " Unmanaged plugin (manually installed and updated) " Plug '~/my-prototype-plugin' " Use release branch (recommend) Plug 'neoclide/coc.nvim', {'branch': 'release'} " Initialize plugin system Plug 'ncm2/ncm2' Plug 'ncm2/ncm2-d', { 'for': 'd' } Plug 'roxma/nvim-yarp' Plug 'majutsushi/tagbar' Plug 'Rasukarusan/nvim-select-multi-line' Plug 'akinsho/toggleterm.nvim' Plug 'tpope/vim-commentary' Plug 'autozimu/LanguageClient-neovim', { \ 'branch': 'next', \ 'do': 'bash install.sh', \ } Plug 'dense-analysis/ale' call plug#end() set number set autoindent set tabstop=4 set shiftwidth=4 set smarttab set softtabstop=4 set mouse=a set encoding=UTF-8 set rtp^="/usr/home/x/.opam/4.13.1+options/share/ocp-indent/vim" set hidden " enable ncm2 for all buffers and set completeopt autocmd BufEnter * call ncm2#enable_for_buffer() set completeopt=noinsert,menuone " Start NERDTree and put the cursor back in the other window. autocmd VimEnter * NERDTree | wincmd p " Exit Vim if NERDTree is the only window remaining in the only tab. autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif nmap :TagbarToggle nnoremap :NERDTreeToggle nnoremap :call CocActionAsync('jumpDefinition') nnoremap :call LanguageClient_contextMenu() nnoremap K :call LanguageClient#textDocument_hover() nnoremap gd :call LanguageClient#textDocument_definition() nnoremap :call LanguageClient#textDocument_rename() nnoremap v :call sml#mode_on() " By applying the mappings this way you can pass a count to your " mapping to open a specific window. " For example: 2 will open terminal 2 nnoremap exe v:count1 . "ToggleTerm" inoremap exe v:count1 . "ToggleTerm" let g:opamshare = substitute(system('opam var share'),'\n$','',) execute "set rtp+=" . g:opamshare . "/merlin/vim" let g:sql_type_default = 'pgsql' let g:NERDTreeDirArrowExpandable="+" let g:NERDTreeDirArrowCollapsible="~" let g:LanguageClient_serverCommands = {'ocaml': ['ocamllsp']} let g:sml#echo_yank_str = 1 " set let g:toggleterm_terminal_mapping = '' let g:ale_sign_error = '✘' let g:ale_sign_warning= '⚠' highlight ALEErrorSign ctermbg=NONE ctermfg=red highlight ALEWarningSign ctermbg =NONE ctermfg=yellow let g:ale_linters_explicit= 1 let g:ale_lint_on_text_changed= 'never' let g:ale_lint_on_enter = 0 let g:ale_lint_on_save= 1 let g:ale_fix_on_save = 1 let g:ale_linters = { \ 'ocaml': ['merlin'], \} let g:ale_fixers = { \ 'ocaml': ['ocamlformat'], \ '*': ['remove_trailing_lines', 'trim_whitespace'], \} :colorscheme jellybeans "gc: comment let g:LanguageClient_serverCommands = { \ 'ocaml': ['ocamllsp'], \} ```
Re: Best Practice to manage large projects with dub?
On Friday, 13 May 2022 at 17:51:55 UTC, Ozan Süel wrote: Hi My situation: I'm working on and with many projects based on many libraries. I know how to handle these in Git, GitHub and Dub. But what would be the Best Practice in current dub? Let's say, we have many apps (1 app = 1 package), which use several libs (Every app has his own set of used libs, some are overlapping with other apps), every lib requires new libs to work (some are overlapping),and so on. Let's say we want to have 10 apps and need in sum 100 packages with every possible combinations. One way would be, to pump the dub package manager with 100 new packages for building only 10 apps. I would like to avoid fill the dub database with small packages it. An deprecated way is to combine dub with github, which still works fine to me. What would be good way to manage many small libs to build few big apps? Maybe the solution is around the corner, but better to ask the experts. Thanks in advance Greetings, Ozan I would highly recommend keeping these small libs in a common repository (a monorepo if you will) but in a manner that only what is needed is required. Lots of projects/repositories/dub.jsons == pain
Best Practice to manage large projects with dub?
Hi My situation: I'm working on and with many projects based on many libraries. I know how to handle these in Git, GitHub and Dub. But what would be the Best Practice in current dub? Let's say, we have many apps (1 app = 1 package), which use several libs (Every app has his own set of used libs, some are overlapping with other apps), every lib requires new libs to work (some are overlapping),and so on. Let's say we want to have 10 apps and need in sum 100 packages with every possible combinations. One way would be, to pump the dub package manager with 100 new packages for building only 10 apps. I would like to avoid fill the dub database with small packages it. An deprecated way is to combine dub with github, which still works fine to me. What would be good way to manage many small libs to build few big apps? Maybe the solution is around the corner, but better to ask the experts. Thanks in advance Greetings, Ozan
Re: What exact debugging information is added to the binary and how to parse it all?
On Friday, 13 May 2022 at 16:11:14 UTC, BoQsc wrote: Haven't used debuggers or debugged a lot just yet, but I've had this question in my mind and I'd like to inspect some debugging information manually. Are there some kind of documentation or specification and are there a lot of information that is hidden in a an average "debuggable" binary? if you're on linux then the debug information are generated in a format that's well specified called DWARF. DWARF essentially contain information about - translation unit filename - call stack - each instruction of the runtime code is associated to a location (allowing to put breakpoints) - the layout of user defined types (allowing to inspect instances) - the inheritance chain of user defined types - the variable types (alowing to inspect variables) That's a lot of information, they non-trivially increase the size of the binary, but this is required to debug a program. [learn more](https://dwarfstd.org/)...
What exact debugging information is added to the binary and how to parse it all?
Haven't used debuggers or debugged a lot just yet, but I've had this question in my mind and I'd like to inspect some debugging information manually. Are there some kind of documentation or specification and are there a lot of information that is hidden in a an average "debuggable" binary?
Re: Back to Basics at DConf?
On Fri, May 13, 2022 at 03:43:09PM +, Johan via Digitalmars-d-learn wrote: > On Thursday, 12 May 2022 at 21:58:33 UTC, Ali Çehreli wrote: > > I am considering proposing a presentation for DConf 2022. > > > > Would a "Back to Basics" style presentation be interesting? If, so > > what exact topic would you like to see? > > Hey Ali, > When I read "Back to basics" on a program language conference, I > imagine Andrei presenting about some simple common task and then at > 3/4 of the presentation there is an amazing trick that speeds it up by > a factor 5, mind is blown and you remember why you like programming so > much. [...] My mental image of this is Ali presenting some simple common task, then at 3/4 of the presentation there's an amazing trick that lets you write it in D in 5 times less code than in other languages, and my mind is blown and I remember why I love D so much. :-P T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
Re: Back to Basics at DConf?
On Thursday, 12 May 2022 at 21:58:33 UTC, Ali Çehreli wrote: I am considering proposing a presentation for DConf 2022. Would a "Back to Basics" style presentation be interesting? If, so what exact topic would you like to see? Hey Ali, When I read "Back to basics" on a program language conference, I imagine Andrei presenting about some simple common task and then at 3/4 of the presentation there is an amazing trick that speeds it up by a factor 5, mind is blown and you remember why you like programming so much. ;-) Johan
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 07:32:16 UTC, Chris Katko wrote: This is a kinda "dynamic language" feature but it feels like this information is theoretically, knowable at static, compile-time. I know what the variable types will be at compile-time, but I don't know how to put them all in one class and reference them automatically. Like `std.json.JSONValue` or `std.variant.Variant` you can also use a struct with a type flag and possible data types that fit for you. Boolean and Integer may share the same memory location via `union` for example. Or just use the built one `Variant` type. In case you only store the pointers to the data, you just need `void*[]` and proper casting.
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 11:58:15 UTC, zjh wrote: On Friday, 13 May 2022 at 08:28:56 UTC, vit wrote: ... ```d ... this(DataSources dataSources){ this.dataSources = dataSources; } ... return new MultiGraph!(staticMap!(PointerTarget, Ts))(ts);//ts ``` How is `ts` convert to `DataSources`? `ts` have same type like `DataSources`: ```d import std.meta : staticMap, allSatisfy; import std.traits : PointerTarget, isPointer; import std.conv : to; alias Pointer(T) = T*; class MultiGraph(Ts...){// Ts == (float, double, int) alias DataSources = staticMap!(Pointer, Ts); // (float, double, int) -> (float*, double*, int*) DataSources dataSources;// -> (float*, double*, int*) float[][DataSources.length] buffers;// -> float[][3] this(DataSources dataSources){ // dataSources == (float*, double*, int*) this.dataSources = dataSources; } void onTick() { //grab datasource data and do something. foreach(enum i, alias d; dataSources) buffers[i] ~= to!float(*d); //or whatever } } auto multiGraph(Ts...)(Ts ts) // Ts == (float*, double*, int*) if(allSatisfy!(isPointer, Ts)){ //all types in Ts are pointers alias DataSources = staticMap!(PointerTarget, Ts); // (float*, double*, int*) -> (float, double, int) return new MultiGraph!(DataSources)(ts); } void main(){ float myFloat; double myDouble; int myInteger; auto g = multiGraph(, , ); } ```
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 08:28:56 UTC, vit wrote: ... ```d ... this(DataSources dataSources){ this.dataSources = dataSources; } ... return new MultiGraph!(staticMap!(PointerTarget, Ts))(ts);//ts ``` How is `ts` convert to `DataSources`?
Re: Back to Basics at DConf?
On Thursday, 12 May 2022 at 21:58:33 UTC, Ali Çehreli wrote: so what exact topic would you like to see? May be you can talk about how to link `d` to`C++`. There are too few examples. Or `D` how to link to `Rust`,etc. I don't even read the `basics` of C++, which is boring. And interested in the interaction between `d` and other languages, especially `C++`. I think it is very meaningful to do a good job in interfacing the library of `C++`.
Re: Back to Basics at DConf?
On Friday, 13 May 2022 at 03:31:53 UTC, Ali Çehreli wrote: On 5/12/22 18:56, forkit wrote: > So...you want to do a talk that challenges D's complexity, by getting > back to basics? I wasn't thinking about challenging complexity but it gives me ideas. I am looking for concrete topics like templates, classes, ranges, rvalues, etc. Are those interesting? Ali Perhaps those are a little too basic for your intended audience (which is?) My first objective when searching for a path towards a solution for a problem, is setting out to find valid methods to solve that problem, and then chosing the best method (based on whatever criteria is appropriate at the time). So, perhaps a talk that focuses on comparing different methods for solving common computational tasks (e.g. search and decision problems), might be more valuable to your audience.
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 07:32:16 UTC, Chris Katko wrote: On Friday, 13 May 2022 at 07:05:36 UTC, vit wrote: On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote: I have an intrinsicGraph(T) class that is given a pointer to a T dataSource and automatically polls that variable every frame to add it to the graph, whether it's a float, double, integer, and maybe bool. [...] I dont understand first qestion but second question has a solution: ```d intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto ref Args args){ return new intrinsic_graph!T(val, args); } instrinsicGraph!float testGraph; instrinsicGraph!ulong testGraph2; // later testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1)); testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1)); ``` Okay, to clarify just in case I'm very confusing because I'm up late. If I wanted a "multipleGraph". A graph that takes multiple values and plots them on the same graph. I need to store a buffer for each dataSource. Luckily, because I'm painting them to the screen, the buffers only really need to be float even if they started as a boolean, int, or double. However, if I'm keeping a list of pointers to things I want to snoop when I call onTick(), I can't think of a way to support multiple types: ```D class intrinsicGraph(T) { T* dataSource; float[] buffer; void onTick() { //grab datasource data and do something. buffer ~= to!float(*datasource); } } auto g = intrinsicGraph!float(); ``` But what if there's multiple types? ```D class multiGraph(???) { ???[] dataSources; float[] buffers; void onTick() { //grab datasource data and do something. foreach(d, i; dataSources) buffers[i] ~= to!float(*d); //or whatever } } auto g = multiGraph!???(, , ); ``` This is a kinda "dynamic language" feature but it feels like this information is theoretically, knowable at static, compile-time. I know what the variable types will be at compile-time, but I don't know how to put them all in one class and reference them automatically. Try variadic templates: ```d import std.meta : staticMap, allSatisfy; import std.traits : PointerTarget, isPointer; import std.conv : to; alias Pointer(T) = T*; class MultiGraph(Ts...){ alias DataSources = staticMap!(Pointer, Ts); DataSources dataSources; float[][DataSources.length] buffers; this(DataSources dataSources){ this.dataSources = dataSources; } void onTick() { //grab datasource data and do something. foreach(enum i, ref d; dataSources) buffers[i] ~= to!float(*d); //or whatever } } auto multiGraph(Ts...)(Ts ts) if(allSatisfy!(isPointer, Ts)){ return new MultiGraph!(staticMap!(PointerTarget, Ts))(ts); } void main(){ float myFloat; double myDouble; int myInteger; auto g = multiGraph(, , ); } ```
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 07:05:36 UTC, vit wrote: On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote: I have an intrinsicGraph(T) class that is given a pointer to a T dataSource and automatically polls that variable every frame to add it to the graph, whether it's a float, double, integer, and maybe bool. [...] I dont understand first qestion but second question has a solution: ```d intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto ref Args args){ return new intrinsic_graph!T(val, args); } instrinsicGraph!float testGraph; instrinsicGraph!ulong testGraph2; // later testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1)); testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1)); ``` Okay, to clarify just in case I'm very confusing because I'm up late. If I wanted a "multipleGraph". A graph that takes multiple values and plots them on the same graph. I need to store a buffer for each dataSource. Luckily, because I'm painting them to the screen, the buffers only really need to be float even if they started as a boolean, int, or double. However, if I'm keeping a list of pointers to things I want to snoop when I call onTick(), I can't think of a way to support multiple types: ```D class intrinsicGraph(T) { T* dataSource; float[] buffer; void onTick() { //grab datasource data and do something. buffer ~= to!float(*datasource); } } auto g = intrinsicGraph!float(); ``` But what if there's multiple types? ```D class multiGraph(???) { ???[] dataSources; float[] buffers; void onTick() { //grab datasource data and do something. foreach(d, i; dataSources) buffers[i] ~= to!float(*d); //or whatever } } auto g = multiGraph!???(, , ); ``` This is a kinda "dynamic language" feature but it feels like this information is theoretically, knowable at static, compile-time. I know what the variable types will be at compile-time, but I don't know how to put them all in one class and reference them automatically.
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On 13/05/2022 7:03 PM, MichaelBi wrote: On Friday, 13 May 2022 at 06:43:30 UTC, rikki cattermole wrote: On 13/05/2022 6:23 PM, MichaelBi wrote: render!("index.dt", showData()); There ya go, template arguments are run at compile time. Unh, then how to dynamically generate pages by using vibe.d Its been a while since I used vibe.d but I think just storing it in a variable first would be enough. https://vibed.org/api/vibe.http.server/render
Re: Template shenannigans with multiple datatypes
On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote: I have an intrinsicGraph(T) class that is given a pointer to a T dataSource and automatically polls that variable every frame to add it to the graph, whether it's a float, double, integer, and maybe bool. [...] I dont understand first qestion but second question has a solution: ```d intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto ref Args args){ return new intrinsic_graph!T(val, args); } instrinsicGraph!float testGraph; instrinsicGraph!ulong testGraph2; // later testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1)); testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1)); ```
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On Friday, 13 May 2022 at 06:43:30 UTC, rikki cattermole wrote: On 13/05/2022 6:23 PM, MichaelBi wrote: render!("index.dt", showData()); There ya go, template arguments are run at compile time. Unh, then how to dynamically generate pages by using vibe.d
Template shenannigans with multiple datatypes
I have an intrinsicGraph(T) class that is given a pointer to a T dataSource and automatically polls that variable every frame to add it to the graph, whether it's a float, double, integer, and maybe bool. This all works fine if you have a single template type. But what if I want ... multiple graphs? I cannot do D class intrinsicGraph(T???) { (void*) dataSources[]; } and have it become whatever datatype I want. Even if I'm always storing the values in a float buffer, the dataSources themselves cannot be multiple types. Basically I'm wondering if there's a way to have D int FPS; float frameTime; // graph myGraph; myGraph.add(); myGraph.add(); and it enumerates through its dataSources array and adds to the relevant buffers. There is a key that might help, they're all types that can resolve to integer or float. I'm not trying to add support for adding myRandomClass or networkPacket. Only things that can resolve down to float in some form. Is there some kind of clue in having an array of Object (the fundamental superclass?)? I don't think this is necessarily a "run time" reflection problem. Because I could make a graph at compile time, and know its of type, say, (T V U). Say, float, double, uint. Some sort of vardiac template. But then how would you store that, unless you use some sort of mixins to write separate variables. (float\* dataSource0 and double\* dataSource1) Or, wrap each pointer in some sort of fat pointer class that stores the type and a void*, and have an array of those fat pointers and and use some compile time voodoo to cast back cast(float)dataSource[0] (zero is always float), cast(uint)dataSource[2] (index 2 has cast(uint) put in). Additional questions: This may sound strange but is there a way to avoid having to specify the template type twice? ```D instrinsicGraph!float testGraph; instrinsicGraph!ulong testGraph2; // later testGraph = new intrinsic_graph!float(units[0].x, 100, 300, COLOR(1,0,0,1)); testGraph2 = new intrinsic_graph!ulong(g.stats.fps, 100, 500, COLOR(1,0,0,1)); ``` It'd be nice if I only had to specify the type once. It'd also be kinda nice if I could hide the fact I need to specify the type at all and have it automatically become whatever type the passed in value is: D instrinsicGraph testGraph(g.stats.fps) //automatically stores an integer buffer.
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On 13/05/2022 6:23 PM, MichaelBi wrote: render!("index.dt", showData()); There ya go, template arguments are run at compile time.
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On Friday, 13 May 2022 at 06:12:01 UTC, rikki cattermole wrote: Okay that is fine, now we need to see where showData is being called. thanks, here's the code: import vibe.vibe; import std.process; import std.conv : to; void main() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["0.0.0.0"]; readOption("port|p", , "Sets the port used for serving HTTP."); readOption("bind-address|bind", [0], "Sets the address used for serving HTTP."); auto router = new URLRouter; router.get("*", serveStaticFiles("public/")); router.registerWebInterface(new ContentController); auto listener = listenHTTP(settings, router); scope (exit) { listener.stopListening(); } runApplication(); } class ContentController { void index() { render!("index.dt", showData()); } } struct Camera{ @name("_id") BsonObjectID id; // represented as "_id" in the database string brand; string model; } Camera[] showData(){ auto uri = environment.get("MONGODB_URI"); MongoClient conn = connectMongoDB(uri); MongoDatabase eqpdb = conn.getDatabase("MbEqpHeroku"); MongoCollection cameras = eqpdb["cameras"]; Camera[] cs; auto results = cameras.find(); foreach(rec;results) cs ~= deserializeBson!Camera(rec); return cs; }
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
Okay that is fine, now we need to see where showData is being called.
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On Friday, 13 May 2022 at 06:01:29 UTC, rikki cattermole wrote: On 13/05/2022 5:52 PM, MichaelBi wrote: struct Camera{ @name("_id") BsonObjectID id; // represented as "_id" in the database string brand; string model; } the structure is mapping of database field structure. how to resolve? That code isn't the cause of your issue (its fine, no CTFE needed). We would need see more of your code surrounding: auto uri = environment.get("MONGODB_URI"); MongoClient conn = connectMongoDB(uri); MongoDatabase eqpdb = conn.getDatabase("MbEqpHeroku"); here is the code: Camera[] showData(){ auto uri = environment.get("MONGODB_URI"); MongoClient conn = connectMongoDB(uri); MongoDatabase eqpdb = conn.getDatabase("MbEqpHeroku"); MongoCollection cameras = eqpdb["cameras"]; Camera[] cs; auto results = cameras.find(); foreach(rec;results) cs ~= deserializeBson!Camera(rec); return cs; }
Re: Help, in vibe.d, how to get configure var of mongodb in heroku?
On 13/05/2022 5:52 PM, MichaelBi wrote: struct Camera{ @name("_id") BsonObjectID id; // represented as "_id" in the database string brand; string model; } the structure is mapping of database field structure. how to resolve? That code isn't the cause of your issue (its fine, no CTFE needed). We would need see more of your code surrounding: auto uri = environment.get("MONGODB_URI"); MongoClient conn = connectMongoDB(uri); MongoDatabase eqpdb = conn.getDatabase("MbEqpHeroku");