Re: Beerconf Noveber 2022 -- Turkey edition

2022-11-17 Thread Ethan Watson via Digitalmars-d-announce
On Saturday, 12 November 2022 at 21:51:38 UTC, Steven 
Schveighoffer wrote:

# BEERCONF!


Reminding myself to remember this for a change.


Re: Emulating DLL

2019-03-20 Thread Ethan Watson via Digitalmars-d-learn

On Wednesday, 20 March 2019 at 19:44:52 UTC, Craig wrote:
Do you agree that, at least in some cases, this is entirely 
feasible and easy?


I literally answered in the affirmative in my first post.

Note that all that Binderoo does is put function pointers in 
places that looks like real code, and does this automatically for 
DLL recompiles.


Everything you just described in your above post overcomplicates 
it from there. Go wild. But you're not going to get far if you 
choose to expand it past your initial examples (as you've 
suggested you might do) if you don't take the above 
implementation details in to account.


Like I literally said in my first post.


Re: Emulating DLL

2019-03-18 Thread Ethan Watson via Digitalmars-d-learn

On Monday, 18 March 2019 at 22:50:57 UTC, Craig wrote:
Is it possible to create a D module that has functions in it, 
and then use those functions dynamically at run time emulating 
DLL like functionality?


On Monday, 18 March 2019 at 22:50:57 UTC, Craig wrote:
Is it possible to create a D module that has functions in it, 
and then use those functions dynamically at run time emulating 
DLL like functionality?


I've talked extensively on this topic at DConf over the last few 
years.


http://dconf.org/2016/talks/watson.html
http://dconf.org/2017/talks/watson.html
http://dconf.org/2018/talks/watson.html

https://github.com/GooberMan/binderoo

It's not a simple thing by any means, there's plenty of little 
implementation details that you'll need to be aware of. But yes, 
it's quite possible.


Re: Of possible interest: fast UTF8 validation

2018-05-16 Thread Ethan Watson via Digitalmars-d

On Wednesday, 16 May 2018 at 14:25:07 UTC, Jack Stouffer wrote:
D doesn't seem to have C definitions for the x86 SIMD 
intrinsics, which is a bummer


Replying to highlight this.

There's core.simd which doesn't look anything like SSE/AVX 
intrinsics at all, and looks a lot more like a wrapper for 
writing assembly instructions directly.


And even better - LDC doesn't support core.simd and has its own 
intrinsics that don't match the SSE/AVX intrinsics API published 
by Intel.


And since I'm a multi-platform developer, the "What about NEON 
intrinsics?" question always sits in the back of my mind.


I ended up implementing my own SIMD primitives in Binderoo, but 
they're all versioned out for LDC at the moment until I look in 
to it and complete the implementation.


Re: Of possible interest: fast UTF8 validation

2018-05-16 Thread Ethan Watson via Digitalmars-d
On Wednesday, 16 May 2018 at 13:54:05 UTC, Andrei Alexandrescu 
wrote:
Is it workable to have a runtime-initialized flag that controls 
using SSE vs. conservative?


Sure, it's workable with these kind of speed gains. Although the 
conservative code path ends up being slightly worse off - an 
extra fetch, compare and branch get introduced.


My preferred method though is to just build multiple sets of 
binaries as DLLs/SOs/DYNLIBs, then load in the correct libraries 
dependant on the CPUID test at program initialisation. Current 
Xbox/Playstation hardware is pretty terrible when it comes to 
branching, so compiling with minimal branching and deploying the 
exact binaries for the hardware capabilities is the way I 
generally approach things.


We never got around to setting something like that up for the PC 
release of Quantum Break, although we definitely talked about it.


Re: Of possible interest: fast UTF8 validation

2018-05-16 Thread Ethan Watson via Digitalmars-d
On Wednesday, 16 May 2018 at 11:18:54 UTC, Andrei Alexandrescu 
wrote:

https://www.reddit.com/r/programming/comments/8js69n/validating_utf8_strings_using_as_little_as_07/


I re-implemented some common string functionality at Remedy using 
SSE 4.2 instructions. Pretty handy. Except we had to turn that 
code off for released products since nowhere near enough people 
are running SSE 4.2 capable hardware.


The code linked doesn't seem to use any instructions newer than 
SSE2, so it's perfectly safe to run on any x64 processor. Could 
probably be sped up with newer SSE instructions if you're only 
ever running internally on hardware you control.


Re: Why is 64-bit dmd not built as part of the Windows release?

2018-05-15 Thread Ethan Watson via Digitalmars-d

On Tuesday, 15 May 2018 at 16:01:28 UTC, Atila Neves wrote:

Isn't it just make -f win64.mak?", I hear you ask.


I wouldn't ask that. Every time I need a 64-bit dmd, I open the 
project in src/vcbuild and let Visual Studio and Visual D take 
care of it.


But I agree with the subject entirely. 64-bit DMD is absolutely 
required for my own usage. The Linux platforms have i386/x64 
downloads. OSX is going 64-bit only. Having both packages 
available for Windows would be much appreciated.


Re: Any video editing folks n da house?

2017-05-29 Thread Ethan Watson via Digitalmars-d
On Wednesday, 24 May 2017 at 09:27:59 UTC, Andrei Alexandrescu 
wrote:
I'm thinking publicly available videos so the footage is 
already out there.


One question I'd want to ask is: What is the legal status of the 
resulting video?


This is purely because of software licensing. My nonlinear 
editing of choice is Davinci Resolve, but I've only ever done it 
for hobby projects that make no money. In the case of providing a 
video authored with the software to the D Foundation, I'm not 
entirely sure the "free" license covers such usage.


(I also doubt I'd have the time to devote to cutting a video at 
this stage, but it's the first question I thought of when viewing 
this thread.)


Re: Please provide DMD as 64 executable

2017-05-21 Thread Ethan Watson via Digitalmars-d

On Sunday, 21 May 2017 at 01:29:58 UTC, Laeeth Isharc wrote:
There a Visual D script, but I do not know how to use that 
using msbuild.


We had some trickiness at work regarding this. You essentially 
need to invoke devenv instead of msbuild if you want to script 
the process.


Of course, now that Visual D supports D files inside a .vcxproj, 
it should probably be upgraded to use one of those instead of the 
.visualdproject file.


Re: Please provide DMD as 64 executable

2017-05-18 Thread Ethan Watson via Digitalmars-d

On Thursday, 18 May 2017 at 13:41:21 UTC, Andre Pany wrote:
I think the 64 bit version of dmd should be the default these 
days;)


I believe this is a Windows-only problem.

For which I'm +1. I have to build my own because compiling some 
Binderoo code with a few objects breaks the memory barrier.


Re: "I made a game using Rust"

2017-05-10 Thread Ethan Watson via Digitalmars-d
On Wednesday, 10 May 2017 at 14:31:28 UTC, Vladimir Panteleev 
wrote:
Internal compiler errors (ICEs) are bugs which are generally 
treated as high priority. Please report them.


See my previous rant on this subject.

http://forum.dlang.org/post/qkxyfiwjwqklftcwt...@forum.dlang.org

tl;dr - Sure, we'll submit bugs, but if someone literally has to 
stop work for a day because they can't tell at a glance what's 
gone wrong when compiling code then that's a massive failure of 
the compiler.


Re: "I made a game using Rust"

2017-05-10 Thread Ethan Watson via Digitalmars-d

On Wednesday, 10 May 2017 at 14:02:38 UTC, Adrian Matoga wrote:

Would you mind giving some examples?


My biggest bugbear with DMD is internal compiler errors giving me 
no meaningful information.


Excepting one or two edge cases with SSE types and the .NET 
compiler, I can get a meaningful error message and an error code 
from MSVC. And you can search them all through the MSDN 
documentation.


https://msdn.microsoft.com/en-us/library/8x5x43k7.aspx

If I find the message isn't that helpful, googling for the error 
code usually brings up discussions on stackoverflow about it.


Even user-inserted #errors have an error code.

https://msdn.microsoft.com/en-us/library/y0tzt8e0.aspx


Re: "I made a game using Rust"

2017-05-10 Thread Ethan Watson via Digitalmars-d

On Wednesday, 10 May 2017 at 13:22:22 UTC, Adam D. Ruppe wrote:
Those of you on IRC know that I've been pushing hard for better 
error messages. I think that is *the* killer feature clang 
offered and I see it brought up again and again.


D used to do well. Now we're lagging behind. No language change 
needed to vastly improve error messages.


I find it a very curious state of affairs myself that Microsoft's 
C++ compiler has significantly better error messages than DMD.


Re: Jonathan Blow's presentation

2017-05-10 Thread Ethan Watson via Digitalmars-d

On Tuesday, 9 May 2017 at 23:47:46 UTC, Era Scarecrow wrote:
Nope, uncompressed. Seems some games they decided the small 
amount of time spent decompressing audio and textures was too 
high, which is why some of the games are 50Gb in size, because 
it's more important to have larger textures than trying to push 
the HD textures and 4k stuff, vs actually having hardware that 
can handle it, since the console hardware is seriously behind 
PC hardware.


On Tuesday, 9 May 2017 at 23:58:13 UTC, Era Scarecrow wrote:
Found an appropriate articles Regarding Titanfall (a few years 
ago), although that's for PC and the reason for giving a boost 
to 'underpowered PC's', although i could have sworn they did it 
for consoles more. Still ridiculous in my mind.


Yeah, you might want to actually read the entire thread before 
stating this stuff again.


Re: Jonathan Blow's presentation

2017-05-09 Thread Ethan Watson via Digitalmars-d

On Monday, 8 May 2017 at 19:14:16 UTC, Meta wrote:
Is this why most console games that get ported to PC are 
massive? GTA V on PC, for example, was 100GB, while Skyrim was 
around 8GB.


Consoles have a fixed hardware level that will give you 
essentially deterministic performance. The quality of assets it 
can handle are generally 1/4 to 1/2 as detailed as what the 
current top-line but reasonably-priced PC hardware can handle. 
And PC gamers *love* getting the higher detailed assets. So we 
ship PC games with the option to scale the quality of the assets 
used at runtime, and ship with higher quality assets than is 
required for a console game.


See as an alternative example: the Shadows of Mordor ultra HD 
texture pack, which requires a 6GB video card and an additional 
download. Another example I like using is Rage, which is 
essentially 20GB of unique texture data. If they wanted to 
re-release it on Xbox One and PS4 without being accused of just 
dumping a port across, they'd want to ship with 80GB of texture 
data.


There's also grumblings about whether those HD packs are worth 
it, but now that 4K displays are coming in those grumblings are 
stopping as soon as people see the results.


On Tuesday, 9 May 2017 at 02:21:19 UTC, Nick Sabalausky 
(Abscissa) wrote:
I don't know anything about Witcher, but FF13 *does* have a 
fair amount of pre-rendered video, FWIW. And maybe Witcher uses 
better compression than FF13?


Correct about the video. The Final Fantasy games are notorious 
for their pre-renders and their lengthy cutscenes. All of which 
require massive amounts of video and audio data.


Better compression though? Unlikely. Texture formats are fairly 
standardised these days. Mesh formats are custom, but not as much 
of a space hog as textures. Other assets like audio and video is 
more where the compression formats come in to play. But gaming 
hardware has a few tricks for that. For example:


On Tuesday, 9 May 2017 at 02:13:19 UTC, Nick Sabalausky 
(Abscissa) wrote:
Uncompressed? Seriously? I assume that really means FLAC or 
something rather than truly uncompressed, but even 
still...sounds more like a bullet-list 
pandering^H^H^H^H^H^H^H^H^Hselling point to the same 
suckers^H^H^H^H^H^H^H"classy folk" who buy Monster-brand cables 
for digital signals than a legit quality enhancement.


Well, no. Gaming consoles - and even mobile devices - have 
dedicated hardware for decompressing some common audio and video 
formats. PC hardware does not. Decompression needs to happen on 
the CPU.


Take Titanfall as a use case, which copped quite a bit of flack 
for shipping the PC version with uncompressed audio. The Xbox One 
version shipped on a machine that guaranteed six hardware threads 
(at one per core) with dedicated hardware for audio 
decompression. Their PC minspec though? A dual core machine (at 
one thread per core) with less RAM and only using general purpose 
hardware.


The PC scene had a cry, but it was yet another case of PC gamers 
not actually understanding hardware fully. The PC market isn't 
all high-end users, the majority of players aren't running 
bleeding edge hardware. They made the right business decision to 
target hardware that low, but it meant some compromises had to be 
made. In this case, the cost of decompressing audio on the CPU 
was either unfeasible in real time or increased load times 
dramatically during load times. Loading uncompressed audio off 
the disk was legitimately an optimisation in both cases.


On Tuesday, 9 May 2017 at 06:50:18 UTC, Ola Fosheim Grøstad wrote:
It isn't all that hard to distinguish if you know what to 
listen for. I hear a big difference in music I have mixed 
down/mastered on a good headset.


So, as Walter would say, "It's trivially obvious to the casual 
observer."


That's the point of the blind test. It isn't trivially obvious to 
the casual observer. You might think it is, but you're not a 
casual observer. That's essentially why LAME started up - a bunch 
of audiophiles decided to encode for perception of quality rather 
than strictly objective quality.


Re: Jonathan Blow's presentation

2017-05-08 Thread Ethan Watson via Digitalmars-d

On Monday, 8 May 2017 at 16:10:51 UTC, Rel wrote:

I don't know if I ever will need it in my code. For the game
development use case it may be useful, for example to package
all of the game assets at compile time.


It's only useful for very select cases when hardcoded assets are 
required. You know, unless you want to try making a 45 gigabyte 
executable for current Playstation/Xbox games. A talk I watched 
the other year made the point that as far as textures go in video 
games, literally all but 10 you'll ever use are read only so stop 
trying to program that exception as if it's a normal thing. 
Hardcoding a select few assets is also a case of a vast-minority 
exception. There's ways to do it on each platform, and it's not 
really worth thinking about too much until those rare times you 
need one.


Embedding inside the executable is also already a thing you can 
do in D with the import keyword.


Re: Jonathan Blow's presentation

2017-05-08 Thread Ethan Watson via Digitalmars-d

On Monday, 8 May 2017 at 13:21:07 UTC, Rel wrote:

What do you guys think of the points explained here:
https://www.youtube.com/watch?v=gWv_vUgbmug

Seems like the language shares a lot of features with
D programming language. However there are several
features that caught my interest:
1) The compile times seems very fast in comparison
with other modern programming languages, I'm wondering
how he managed to do it?
2) Compile-time execution is not limited, the build
system is interestingly enough built into the language.


I was at that talk, and spoke to him quite a bit there. He also 
attended my talk. And yes, there is quite a bit of overlap in 
terms of features. He's well in to design by introspection, for 
example.


I can answer #1, I know a few things there but that's more 
something he should talk about as I don't know how public he's 
made that knowledge.


I also put forward to him a case with regards to compile time 
execution and code generation. Say you've got a global variable 
that you write to, and reading from that changes the kind of code 
you will generate. Thus, your outputted code can be entirely 
different according to whenever the compiler decides to schedule 
that function for execution and compilation. His response was, 
"Just don't do that."


That's essentially the philosophical difference there. Jonathan 
wants a language with no restrictions, and leave it up to the 
programmer to solve problems like the above themselves. Whether 
you agree with that or not, well, that's an entirely different 
matter.


Re: DLang quarterly EU?

2017-05-07 Thread Ethan Watson via Digitalmars-d

On Sunday, 7 May 2017 at 11:32:53 UTC, Adam Wilson wrote:

On 5/7/17 12:57, Seb wrote:
+1 - maybe its worth considering to make it for two days (=one 
weekend)


That can work. It would be two or three days vacation depending 
on flight schedules.

...
Not to mention a cool way to see new cities if it moves around.


Yes, that was the intention on both counts. There's no point to 
flying somewhere just for the day. Especially since there will 
doubtless be Micro BeerConfs in the evening ;-)


Andrei suggested that Bucharest be the first city we hold this 
in. Sounds like a great plan to me.


DLang quarterly EU?

2017-05-06 Thread Ethan Watson via Digitalmars-d
I was speaking to Atila earlier about the things we like about 
DConf. Sitting around talking to a bunch of computer scientists 
is fantastic, and not something people generally get to do in 
their chosen careers as a programmer.


EU nations are quite close together. Rather than a city meet up 
monthly, what about a continental meet up quarterly?


This is quite feasible in Europe, since everything is quite close 
together. I'm keen. Atila is keen. Anyone else think this is a 
great idea?


Re: DConf 2017 Berlin - Streaming ?

2017-05-05 Thread Ethan Watson via Digitalmars-d
I've put my slides up on Slideshare. They should show up on the 
DConf website some time soon too.


https://www.slideshare.net/EthanWatson5/binderoo-a-rapid-iteration-framework-that-even-scripters-can-use



Re: See you soon at dconf

2017-05-03 Thread Ethan Watson via Digitalmars-d

On Wednesday, 3 May 2017 at 09:04:31 UTC, John Colvin wrote:
I'm guessing everyone will be converging on the conference 
hotel as the day goes on?


I imagine I'll wander by there. I'm not staying there, but it is 
a quick walk to my accommodation. I land at 20.45 though, so I 
hope it's still going around 22.30-23.00.


Re: Cityhash in D?

2017-03-26 Thread Ethan Watson via Digitalmars-d

On Wednesday, 15 March 2017 at 13:26:45 UTC, Ethan Watson wrote:

Does anyone know of a D implementation of Google's Cityhash?


https://github.com/Remedy-Entertainment/cityhash-d

64-bit functions only for now. I'll add the 32-bit functions at 
some point, likely when I need them.




Re: Cityhash in D?

2017-03-15 Thread Ethan Watson via Digitalmars-d

On Wednesday, 15 March 2017 at 13:37:41 UTC, Andrea Fontana wrote:

It seems pretty easy to use with dstep, isn't it?


I need to use it at compile time. Linking as a C lib is 
subsequently out of the question.


Cityhash in D?

2017-03-15 Thread Ethan Watson via Digitalmars-d

https://github.com/google/cityhash

Does anyone know of a D implementation of Google's Cityhash? My 
google-fu has failed me and I've been unable to find one.


Re: Rename 'D' to 'D++'

2017-03-10 Thread Ethan Watson via Digitalmars-d

On Friday, 10 March 2017 at 11:25:11 UTC, Traktor TOni wrote:
I think the name is just misleading, the D developers should at 
least be honest with themselves.


D++ - Because no language has version numbers. Not even C#. Any 
proof to the contrary is clearly fake proof.


Re: My next D related talk

2017-02-08 Thread Ethan Watson via Digitalmars-d

On Wednesday, 8 February 2017 at 02:02:27 UTC, extrawurst wrote:

Hey congratz Ethan! By the way will you be at GDC in 3 weeks ?


I won't be at GDC. A few other people from Remedy will be.


Re: My next D related talk

2017-02-07 Thread Ethan Watson via Digitalmars-d

On Tuesday, 7 February 2017 at 15:20:23 UTC, Ethan Watson wrote:

http://www.rebootdevelop.hr/speakers/


I forgot to mention. I may not submit a DConf talk this year as a 
result. But I do want to attend, and I will see if one of the 
other Remedy guys wants to give a talk (he's been working on an 
ARC garbage collector for our usage that will get pushed out to 
Binderoo at some point).


My next D related talk

2017-02-07 Thread Ethan Watson via Digitalmars-d

http://www.rebootdevelop.hr/speakers/

Somewhere down the bottom of that list of speakers is my name. 
I'll be there talking about Binderoo, and will be announcing the 
first stable release at that conference.


The speaker list is an all-star line up of game development. Just 
a few examples:


Tim Cain (Fallout)
SUDA51 (Grasshopper games)
CliffyB (Epic, Gears of War)
Chris Taylor (Total Annihilation)
Chet Faliszek (Team Fortress 2, Portal 2)
Koji Igarashi (Castlevania: Symphony of the Night)
Chris Avellonne (Planescape: Torment)

Just being on the same list as those names is intimidating.

But of note, Jonathan Blow will also be speaking there. I expect 
he'll be doing a Jai thing. I also expect I'll have to answer 
some of his questions during my talk. Which will get *very* 
interesting indeed.


Re: Got the official feedback for my GDC Europe talk

2017-01-21 Thread Ethan Watson via Digitalmars-d
On Saturday, 21 January 2017 at 16:32:36 UTC, Andrei Alexandrescu 
wrote:
Congratulations, that looks like a very good performance! Could 
you please explain a bit how the Google Slides feature you 
mentioned works? -- Andrei


The core functionality is that a web link is provided that allows 
people to enter questions. Visitors to this web link can also 
upvote questions they want to see answered. These questions show 
up on the secondary window used by the speaker to control the 
presentation. At any time, the speaker can click on a question 
and the slides being displayed will be replaced by the question. 
Another click and you've either selected another question; or 
you're back to the presentation.


There's a few implementation details to keep in mind. It requires 
the presentation monitor to be a separate display to your laptop 
monitor etc. The default rendering actually shrinks your 
presentation so that it can display that web link at the top of 
the presentation - which I decided was rubbish so I installed 
Stylebot on Chrome and altered the CSS to keep the presentation 
at full size but overlay the question link (which requires you to 
keep blank space at the top of your presentation)


Question sessions also keep their history for later review.

The part that works out very well is that it forces people to 
keep their questions short and to the point; and since it's a 
vote system you don't end up spending a ton of time on questions 
that only one or two people in the audience are interested in.


Re: Got the official feedback for my GDC Europe talk

2017-01-20 Thread Ethan Watson via Digitalmars-d

On Friday, 20 January 2017 at 12:28:54 UTC, Jacob Carlborg wrote:


Was there a recording uploaded?


It's behind GDC's paywall. Need to see if I can release it from 
its prison.


Got the official feedback for my GDC Europe talk

2017-01-20 Thread Ethan Watson via Digitalmars-d
Landed in my inbox while I was on holiday in Australia (why did I 
leave it three and a half years between visits jeez never do that 
again you fool).


http://imgur.com/a/I6GrF

In summary:

* 4.5 out of 5 audience rating. Average was 4.22.
* Head count of 51. I assume the entire rest of the conference 
was at John Romero's talk.

* Written feedback was very positive.
* Taking questions during the talk via the Google Slides feature 
was seen as a *very* good thing. I will run the same format for 
the DConf talk I plan on submitting, keep the runtime under 
control that way.
* Some people wanted more actual usage of the language than what 
we did to facilitate rapid development with the language. Fair 
call, but not the kind of talk I wrote.


Re: Compiler performance with my ridiculous Binderoo code

2016-12-11 Thread Ethan Watson via Digitalmars-d

On Sunday, 11 December 2016 at 19:40:21 UTC, safety0ff wrote:
That's not really useful for understanding and making progress 
on the issue.


Uh, it kinda does actually. It's highlighting that a better hash 
function will only have a minor effect. The time sink is the 
number of instantiations that are happening.


But it is worth pointing out that, yes, for you to see the 
problem here you won't see it with simple tests. Binderoo very 
quickly builds up recursive template instantiations that bring 
the problem out from the crypt and in to the light.


Compiler performance with my ridiculous Binderoo code

2016-12-11 Thread Ethan Watson via Digitalmars-d
I've been keeping in contact with Stefan and providing him 
example code to test with his CTFE engine. He's been saying for a 
while that templates are slow. So I decided to finally work out 
just how slow we're talking about here.


I can't show the exact code I'm running with, but needless to say 
this particular test case crashes the 32-bit dmd.exe that comes 
with the official downloads. I've had to build my own 64-bit 
version... which also eventually crashes but only after consuming 
8 gigabytes of memory.


Using Visual Studio 2015's built in sample-based profiler, I 
decided to see just what the compiler was doing on a release 
build with the problem code.


http://pastebin.com/dcwwCp28

This is a copy of the calltree where DMD spends most of its time. 
If you don't know how to read these profiles, the good one to 
look at is that it's 130+ functions deep in the callstack. Plenty 
of template instances, plenty of static if, plenty of static 
foreach... I'm doing quite a bit to tax the compiler in other 
words.


Which got me thinking. I've been rolling things over to 
CTFE-generated string mixins lately in anticipation for the 
speedups Stefan will get us. But there's one bit of template code 
that I have not touched at all.


https://github.com/Remedy-Entertainment/binderoo/blob/master/binderoo_client/d/src/binderoo/binding/serialise.d

This is a simple set of templated functions that parses objects 
and serialises them to JSON (the reason I'm not just using 
std.json is because I need custom handling for pointers and 
reference types). But it turns out this is the killer. As a part 
of binding an object for Binderoo's rapid iteration purposes, it 
generates a serialise/deserialise call that instantiates for each 
type found. If I turn that code generation off, the code 
compiles. If I remove a file that has 1000+ structs 
(auto-generated) with tree-like instances embedded in the only 
object I apply Binderoo's binding to in that entire module, it 
compiles in 45% of the time (12 seconds versus 26 seconds).


The hot path without that 1000+ struct file actually goes through 
the AttribDeclaration.semantic and 
UserAttributeDeclaration.semantic code path, with the OS itself 
doing the most work for a single function thanks to 
Outbuffer::writeString needing to realloc string memory in 
dmd\backend\outbuf.c.


The hot path with that 1000+ struct file spends the most time in 
TemplateInstance.semantic, specifically with calls to 
TemplateDeclaration.findExistingInstance, 
TemplateInstance.tryExpandMembers, and 
TemplateInstance.findBestMatch taking up 90%+ of its time. 
finExistingInstance spends most of its time in arrayObjectMatch 
in dtemplate.d, which subseuqently spends most of its time in the 
match function in the same file (which calls virtuals on 
RootObject to do comparisons).


At the very least, I now have an idea of which parts of the 
compiler I'm taxing and can attempt to write around that. But I'm 
also tempted to go in and optimise those parts of the compiler.


Re: CTFE Status

2016-12-11 Thread Ethan Watson via Digitalmars-d

On Sunday, 11 December 2016 at 09:13:41 UTC, Stefan Koch wrote:

Originally I planned for this to over in 3 months.
Now I am going finish the 6th month and it won't be done 
completely.


I hear that.

As an anecdote, by Binderoo work has been functional for months; 
but it's only now becoming usable by normal people. And then once 
normal people use it, there's gonna be tons of bugs and edge 
cases that I need to blitz through. But I will have a framework 
that people can use to do Unity-style development of code using D 
as their rapid iteration language at the end of it.


I've been moving more stuff out of templates and in to CTFE in 
anticipation for this work hitting main.


Re: Inline aggregate types

2016-12-05 Thread Ethan Watson via Digitalmars-d
On Monday, 5 December 2016 at 11:57:18 UTC, Guillaume Chatelet 
wrote:
Do you plan on contributing this back to phobos? I also came 
across this exact same problem.


It'll want to go through a few polish iterations before I even 
think of doing that; and it'll need support for things like 
toString/toHash/etc.


Another critical bit of functionality that std.bitmanip provides 
that I currently don't is a bit array. I also want to support 
statically sized bit arrays, Phobos only provides support for 
dynamically sized.


Re: Inline aggregate types

2016-12-02 Thread Ethan Watson via Digitalmars-d

On Friday, 2 December 2016 at 10:16:17 UTC, Jacob Carlborg wrote:

Using an alias without a template constraint works for me.


I was attempting to support all methods. new class isn't the 
cleanest way of doing things either, so I decided I'd support all 
the things and let the user choose what they're comfortable with.


But I did derp a bit, and realised that I could have just changed 
the string mixin method to not invoke the main template with 
typeof( return value ).


Thus:

mixin template BitPack( alias Descriptor, string NameAlias = 
typeof( Descriptor ).stringof )

{
  mixin( GenerateBitPackBody!( typeof( Descriptor ), NameAlias 
)() );

}

mixin template BitPack( string ElementDescriptor, string 
NameAlias = "BitPackData" )

{
  mixin( "mixin BitPack!( { struct BitPackData { " ~ 
ElementDescriptor ~ " } return BitPackData.init; }(), NameAlias 
);" );

}

Works for both string definitions and inlined new class 
definitions.


Re: Inline aggregate types

2016-12-02 Thread Ethan Watson via Digitalmars-d

On Friday, 2 December 2016 at 08:33:17 UTC, Jacob Carlborg wrote:

But wWhat about an anonymous class as ag0aep6g mentioned?


Usability I see is something that is key here. Having to do a 
typeof yourself is one extra step away from an intuitive API.


So I tried making a definition like this:

mixin template BitPack( Descriptor instance, string NameAlias = 
Descriptor.stringof )

{
  mixin( GenerateBitPackBody!( Descriptor, Descriptor.stringof 
)() );

}

...but I can't work out how to make the template evaluator treat 
descriptor as a templated type without explicitly defining that 
type as the first parameter.


Even trying:

mixin template BitPack( alias Descriptor ) if( is( typeof( 
Descriptor ) ) )


or:

mixin template BitPack( alias Descriptor ) if( __traits( 
compiles,  ) )


wasn't getting me valid code (in the case of the latter, it 
claims it's not a valid template value argument; in the former, 
it meant I would have needed to add additional constraints to the 
other BitPack template).


I bet there's a trick out there that'll let me do what I want. 
But I won't go looking for it at least.


Re: Inline aggregate types

2016-12-01 Thread Ethan Watson via Digitalmars-d

On Thursday, 1 December 2016 at 20:31:32 UTC, Ethan Watson wrote:

https://github.com/Remedy-Entertainment/binderoo/blob/master/binderoo_client/d/src/binderoo/bitpacking.d


Stefan also reminded me that this would be a perfect spot where 
__symbol CTFE variables would make life much easier (especially 
since my entire implementation of the BitPack templates lean 
heavily on CTFE for code generation).


http://forum.dlang.org/post/kqyqnxrirjhtnpvfb...@forum.dlang.org


Re: Inline aggregate types

2016-12-01 Thread Ethan Watson via Digitalmars-d

On Thursday, 1 December 2016 at 20:58:53 UTC, H. S. Teoh wrote:

In cases like these, q{} comes to the rescue:


I had precisely zero idea this existed.


Re: Inline aggregate types

2016-12-01 Thread Ethan Watson via Digitalmars-d
On Thursday, 1 December 2016 at 20:57:13 UTC, Andrei Alexandrescu 
wrote:
The simplest way to go here is to accept an initializer for the 
entire ubyte/ushort/uint/ulong underlying the bitfields. -- 
Andrei


In terms of efficiency at compile time, indeed. But there's 
multiple paths there. You could assign to the value directly, 
which would require intimate knowledge of how the implementation 
works. Which then means you'd need a helper.


Under the hood for my implementation, in fact, it makes that 
single initializer for the bitfield. I'm currently storing in a 
ubyte array that stores in multiples of 4 bytes, and as a part of 
parsing the defined struct it also creates an initializer for 
that array. I'll have to do a bit more work so that I can also 
specify the underlying storage type or intelligently work it out 
(the example I used here, in fact, would only ever want one byte 
of storage to match C++ built-in bitfields exactly unless I'm 
mistaken).


Inline aggregate types

2016-12-01 Thread Ethan Watson via Digitalmars-d

https://github.com/Remedy-Entertainment/binderoo/blob/master/binderoo_client/d/src/binderoo/bitpacking.d

So I've been not-all-that-pleased with std.bitmanip.bitfields for 
a while. It's nice that it's there, but I'm binding to C++ 
objects where the meaningful default values require those packed 
values to have initial values. It's rather painful to get that 
working with the Phobos implementation.


I wanted to make a bitfield where you would simply give it a 
dummy struct type, complete with UDAs to tell it how many bits to 
take as well as standard default values. For example:


struct SomeBitField
{
  @PackSize( 3 ) int iSomeInt = 3;
  @PackSize( 1 ) bool bSomeBool = true;
  @PackSize( 4 ) int iSomeOtherInt;
}

I also don't want this struct to exist outside of the mixin 
declaration for it. Essentially, I want the code to boil down to:


mixin BitPack!( struct {
  @PackSize( 3 ) int iSomeInt = 3;
  @PackSize( 1 ) bool bSomeBool = true;
  @PackSize( 4 ) int iSomeOtherInt;
} );

Nice. Readable. Maintainable. You don't even need to read the 
documentation to add new members to the bit field, or change 
default values.


The compiler disagrees though. The second it sees that struct 
keyword, it freaks out. Sigh. Alrighty, what if we just remove 
the struct keyword? Nope. It tells me that I'm actually passing a 
lambda in to the BitPack mixin template.


Right. If that's the way you want to play compiler:

mixin template BitPack( Descriptor )
{
  mixin( GenerateBitPackBody!( Descriptor )() );
}

mixin template BitPack( string ElementDescription )
{
  mixin( "mixin BitPack!( typeof( { struct BitPackData { " ~ 
ElementDescription ~ " } return BitPackData.init; }() ) );" );

}

What in Zod's name is that abomination? Well. If it thinks it's a 
lambda that I'm trying to pass it, let's just make it explicit. 
I'll make an actual function literal. Take in the variables I 
want as a string instead of a plain old struct. Use a string 
mixin to generate this lambda. Get a typeof of the return type 
(deep in to Voldemort territory here) and passing that along to 
the main BitPack mixin template. And because I *really* don't 
want that struct to persist, my mixin template that takes the 
string descriptor inlines the entire thing with a string mixin.


So the invokation, while not as readable, looks like:

mixin BitPack!( "@PackSize( 3 ) int iSomeInt = 3; @PackSize( 1 ) 
bool bSomeBool = true; @PackSize( 4 ) int iSomeOtherInt;" );


I'm sure I just made someone cry looking at that.

I'm also sure there's plenty of other legit uses for inline 
aggregate types. So while the feature doesn't exist in the 
language yet, at least you can now see that there's quite a legit 
hacky-as-all-fuck workaround for it.


Re: So these two compile and, in non-debug builds, run just fine

2016-11-25 Thread Ethan Watson via Digitalmars-d
On Friday, 25 November 2016 at 15:30:35 UTC, Steven Schveighoffer 
wrote:
But I think Walter's scope changes (DIP 1001 I think?) will 
make it so the compiler rejects this even in non-safe mode.


-Steve


I really hope this is the case. Because, it needs to be said. If 
a modern language fails something like this then it's really not 
good enough in a modern, security-focused environment.


So these two compile and, in non-debug builds, run just fine

2016-11-25 Thread Ethan Watson via Digitalmars-d

MyClass* getAPointer()
{
  MyClass* ptr;
  MyClass instance = new MyClass();
  ptr = 
  return ptr;
}

MyStruct* getAnotherPointer()
{
  MyStruct* ptr;
  MyStruct instance;
  ptr = 
  return ptr;
}

One of the guys here is working on some GC stuff (ARC related), 
and gave me a snippet of code that took a reference to a class on 
the stack, and assigned the address of it to another variable. 
Which meant that when the class reference goes out of scope, it's 
pointing to data on the stack that shouldn't be valid.


And you can break it in debug with a little bit of code as such:

MyClass* ptr = getAPointer();
MyStruct* someStruct = getAnotherPointer();
writeln( to!string( (*ptr).foo ) );

I wouldn't expect this to be something that can be detected at 
compile time. I mean, the code looks simple enough, but it's just 
the easiest way to show off the larger problem that returning by 
pointer is not validated. Ten minutes and you could write some 
horribly obfuscated code that still gives a return value that's a 
stack pointer.


I'm sure this sounds bad. And it is.

Related to this: 
https://msdn.microsoft.com/en-us/library/8dbf701c.aspx


The Windows App Certification Kit can pick up if the security 
token check isn't done on enter and exit of a function. And even 
if the codegen does the checks, stack pointers mean you can start 
doing stack overflows.


Re: Code signing to help with Windows virus false positives

2016-11-03 Thread Ethan Watson via Digitalmars-d

http://imgur.com/5DnCWYw

One of our guys just tried compiling and running a simple Hello 
World program. F-Secure jumped right in.


Code signing the compiler isn't enough. It's been a persistent 
problem around here with DMD generated binaries that F-Secure 
will pick it up. Needless to say, if this happens out in the wild 
with one of our games you won't want me to paste a single line 
from the feedback we'll get about the game not working.


Turns out we have some good contacts at F-Secure though. So I can 
see about getting the problem fixed at the detection level - and 
because of the way the security community operates, that 
knowledge should flush across to things like Windows Defender.


Re: Binding temporaries to ref [WAS: I close BIP27. I won't be pursuing BIPs anymore]

2016-10-21 Thread Ethan Watson via Digitalmars-d
On Thursday, 20 October 2016 at 19:49:42 UTC, Andrei Alexandrescu 
wrote:
I think a solid DIP addressing the problem would have a good 
chance to get traction.


I think all the information in this thread and the "Binding 
rvalues to const ref in D" thread that Atilla started is enough 
for me to write up a solid DIP.


I'll start doing that. Hopefully I'll get a draft up that I'll 
pass to Manu for comment/input this weekend before posting it 
properly.


Re: Binding rvalues to const ref in D

2016-10-20 Thread Ethan Watson via Digitalmars-d

On Thursday, 20 October 2016 at 10:36:16 UTC, Manu wrote:
DIP25 introduced return ref to address this issue. Just 
annotate it correctly?


I mean, it'll work, but it's not the most secure method to rely 
on the programmer remembering to do it.


Re: I close BIP27. I won't be pursuing BIPs anymore

2016-10-20 Thread Ethan Watson via Digitalmars-d
On Wednesday, 19 October 2016 at 10:32:56 UTC, Walter Bright 
wrote:

Better:

   void f(ref Vector v);
   void f(Vector v) { f(v); }

   f(Vector(10,20,30));


Suitable enough for simple functions. But beyond that becomes 
maintenance hell.


For example:

void func2( ref const( Vector ) v1, ref const( Vector ) v2 );

Requires the following permutations:

void func2( const( Vector ) v1, ref const( Vector ) v2 ) { func2( 
v1, v2 ); }
void func2( ref const( Vector ) v1, const( Vector ) v2 ) { func2( 
v1, v2 ); }
void func2( const( Vector ) v1, const( Vector ) v2 ) { func2( v1, 
v2 ); }


For example:

void func3( ref const( Vector ) v1, ref const( Vector ) v2, ref 
const( Vector ) v3 );


Requires the following permutations:

void func3( const( Vector ) v1, const( Vector ) v2, const( Vector 
) v3 ) { func3( v1, v2, v3 ); }
void func3( ref const( Vector ) v1, const( Vector ) v2, const( 
Vector ) v3 ) { func3( v1, v2, v3 ); }
void func3( ref const( Vector ) v1, ref const( Vector ) v2, 
const( Vector ) v3 ) { func3( v1, v2, v3 ); }
void func3( ref const( Vector ) v1, const( Vector ) v2, ref 
const( Vector ) v3 ) { func3( v1, v2, v3 ); }
void func3( const( Vector ) v1, ref const( Vector ) v2, ref 
const( Vector ) v3 ) { func3( v1, v2, v3 ); }
void func3( const( Vector ) v1, const( Vector ) v2, ref const( 
Vector ) v3 ) { func3( v1, v2, v3 ); }
void func3( const( Vector ) v1, ref const( Vector ) v2, const( 
Vector ) v3 ) { func3( v1, v2, v3 ); }


Did I miss one in that block? I think I missed one. Thus my 
point. If you were to provide something that Just Works(TM) out 
of the box for all possible creation states of your ref 
variables, you need to permute on all the ref parameters in your 
function. Which is either a process prone to human error; or in 
automated binding code, more things to parse at compile time 
resulting in slower compile times.


Re: Binding rvalues to const ref in D

2016-10-20 Thread Ethan Watson via Digitalmars-d

On Wednesday, 19 October 2016 at 21:19:03 UTC, Atila Neves wrote:
On Wednesday, 19 October 2016 at 15:58:23 UTC, Chris Wright 
wrote:
So it seems like the compiler could take care of this by only 
providing lvalue references but automatically creating those 
temporary variables for me. It's going to create an extra copy 
that might not be needed if there were a special rvalue 
reference type modifier, but why should I care? It's exactly 
as efficient as the code the compiler forces me to write.


This is what Ethan Watson has suggested, too.


Interesting. Also, I must have missed that suggestion.


It actually went a bit further than my suggestion, if I'm reading 
the summary correctly.


For example, right now we go:

Vector3 vSomeTempName = v1 + v2;
someVectorFunc( vSomeTempName );

This will keep the vSomeTempName entirely in scope and living on 
the stack for as long as that code block is active. A 
simplification step would be to store rvalues on the stack 
without needing to name them, and only destroying them once the 
block's scope goes out of scope.


It still provides an easy escape from a C++ function though. For 
example:


D code:

return someVectorFunc( v1 + v2 );

C++ code:

const Vector3& someVectorFunc( const Vector3& someVector )
{
  return someVector;
}

You'd still want to insert some sanity checking code in the code 
gen to throw an exception if the C++ function is returning a 
reference to the current stack and your D function is also 
returning by reference.


Re: rt_init, rt_term and _initCount

2016-10-20 Thread Ethan Watson via Digitalmars-d
On Thursday, 20 October 2016 at 07:17:49 UTC, Benjamin Thaut 
wrote:
Any suggestions how to solve this problem? Who are other 
platforms doing it?


Would this also be a bigger problem if people use LoadLibrary and 
don't FreeLibrary after?


Re: I close BIP27. I won't be pursuing BIPs anymore

2016-10-19 Thread Ethan Watson via Digitalmars-d

On Wednesday, 19 October 2016 at 09:34:39 UTC, Manu wrote:
I dunno how it could have not been considered, since it was the 
exact
example I've given every time, and the exact case that 
motivated my first
(and many subsequent) posts on this forum back when we still 
worked at
Krome.. all this time later I *still* just wanna call functions 
in games

engines that receive a vector or matrix ;)


Well, it could very well have been the specifics as we laid it 
out that weren't considered, ie avoiding temporary variables that 
we never use again; and taking by const reference to avoid 
copying the struct to the stack (whether just created or already 
previously stored on the stack etc).


Win64 also has the __vectorcall calling convention, but that 
doesn't help in cases where you pass in several matrices as 
inputs for example. And it's not portable to other viable gaming 
platforms.


https://msdn.microsoft.com/en-us/library/dn375768.aspx


Re: I close BIP27. I won't be pursuing BIPs anymore

2016-10-19 Thread Ethan Watson via Digitalmars-d

On Wednesday, 19 October 2016 at 05:41:17 UTC, Manu wrote:

People just want to be able to do this:

  void f(ref const(Vector) v);

  f(v1 + v2);

or:

  f(Vector(10,20,30));

That is all. The rval produces a temporary, and the temporary 
is passed to the function.


Probably worth pointing out that we laid it out exactly like this 
to Walter and Andrei at DConf, and how not having it made the 
Quantum Break animation code (all of which is 3D math) a pain to 
write thanks to having to define the temporary variables 
yourself. Especially when you're calling bound C++ functions and 
the programmers involved could compare it to C++ directly saying 
"Why can't we do this?"


This was actually a use case that had not been considered before, 
as it turns out.





Re: Can you shrink it further?

2016-10-11 Thread Ethan Watson via Digitalmars-d

On Tuesday, 11 October 2016 at 10:01:41 UTC, Stefan Koch wrote:

On Tuesday, 11 October 2016 at 09:45:11 UTC, Temtaime wrote:


Sorry this was also a type in the code.

void popFront7(ref char[] s) @trusted pure nothrow
{
  import core.bitop;
  auto v = 7 - bsr(~s[0] | 1);
  s = s[v > 6 ? 1 : (v ? (v > s.length ? s.length : v) : 
1)..$];

}

Please check this.


162 us


The branching, it hurts my eyes!

Something like the following should give correct (assuming I 
haven't written bad logic) branchless results with 
architecture-optimised max calls. Note that the minus/plus 1 
operation on the third line will ensure with the sign 
multiplication that values of 7 will map to 1, whereas for all 
other values it's an extra operation. But the advantage is that 
you're not sticking three branches in close proximity to each 
other, so you will never get a branch predictor fail. (Of note, 
any performance test for these functions should test with data 
designed to fail the branching code I quoted, keeping in mind 
that desktop Intel processors have a four-state branch predictor. 
I've not performance tested it myself, but this will certainly 
run faster on the AMD Jaguar processors than a version with 
branching checks.)


int v = 7 - bsr( ~s[0] | 1 );
int sign = ( (v - 7) >> 31 );
v = ( v - 1 ) * sign + 1;
str = str[ min( v, s.length ) .. $ ];


Re: color lib

2016-10-10 Thread Ethan Watson via Digitalmars-d

On Monday, 10 October 2016 at 12:10:56 UTC, Jacob Carlborg wrote:

Isn't std.typecons.Flag metaprogramming ;)


Hahaha, oh wow. If ever there was a case for mixins.


Re: color lib

2016-10-10 Thread Ethan Watson via Digitalmars-d

On Saturday, 8 October 2016 at 13:06:42 UTC, Manu wrote:

Oh no, you too? >_<


Yeah, I've been going on a readability bender lately, especially 
in public facing code.


My thinking there is that statements in code that don't 
immediately give context are essentially a cipher. Because that's 
exactly what you need to do to understand the code - look 
something up to see what it means. Named parameters and variable 
names that provide the context avoid that to a large degree.


I'm especially trying to make Binderoo readable as there's so 
many programmers that are scared by metaprogramming. My GDCE talk 
spent a lot of time attempting to make it all understandable. 
Making the code descriptive seals the deal. If I can make my code 
more descriptive, and it compiles out just the same but makes the 
compiler do a bit more work... Make the compiler do more work and 
optimise the compiler.


I'm far more lax on not-publicly-facing code (so basically API 
implementations and supporting code that isn't part of a public 
interface). Anything I expect someone other than myself to 
interact with gets the readability treatment. Which, as you know, 
is important because readable code generally isn't efficient code 
- as is evidenced by the vectorisation/buffer processing thread 
going on in here.


It's also interesting how many programmers get vehemently 
defensive when you call out non-descriptive programming practices 
as programming for your own convenience and no one else. I have 
this argument with using i/j/k/foo/bar/etc in loops as well.


Incidentally, have you had a geez over the core API? An 
efficient API

will emerge when we work out how to work batched operations into
ranges...


Been slowly making my way through it. Seems solid enough, but I 
haven't looked through it all thoroughly yet.


Re: color lib

2016-10-07 Thread Ethan Watson via Digitalmars-d

On Friday, 7 October 2016 at 01:57:06 UTC, Manu wrote:
Regarding 'Linear.No'... yeah... I dunno. I've had this 
argument before.

I really hate that pattern. If it's required, I'll do it


At least as far as readability goes, explicit parameterisation 
lets you understand the invocation at a glance rather than 
already knowing the actual name of the parameter or having to go 
elsewhere in code to see the prototype. For a library, I'd favor 
readability.


Re: debugging mixins

2016-10-03 Thread Ethan Watson via Digitalmars-d

On Monday, 3 October 2016 at 11:42:25 UTC, Stefan Koch wrote:

@Ethan can you share code illustrating your usecase.
(My head is inside compiler internals and building test-code is 
a rather unpleasant context switch)


You should be able to do everything with the example code you 
have. My intention there is to compile everything in the 
acorelibrary module in to a library and statically link against 
that. As such, you'll want to do the .di generation on those 
files. The behaviour right now is that all the Binderoo mixins 
will not expand.


Re: debugging mixins

2016-10-02 Thread Ethan Watson via Digitalmars-d

On Sunday, 2 October 2016 at 05:00:07 UTC, Stefan Koch wrote:
We should create a file where the string-mixins are expanded, I 
agree.


Further to this. I tried generating .di files the other day for 
code based on Binderoo. None of the mixins were expanded, which 
resulted in the compiler needing to do all that work again anyway 
and negating the effect of a precompiled library.


If you get to doing that work, it would be fab if you could apply 
it to .di generation. If not as the default, then at least as a 
switch I can provide on the command line.


Re: Implement the "unum" representation in D ?

2016-09-21 Thread Ethan Watson via Digitalmars-d

On Tuesday, 20 September 2016 at 22:52:57 UTC, Nic Brummell wrote:

If anyone is still interested in this concept whatsoever


Now that we've announced we're doing multiplayer games. One of 
the guys was saying we'd need a fixed-point library. My response 
was "Why not unums?" Thus, in the very near future I'll be 
looking at evaluating the available C++ and D libraries for unums 
to see how suitable they will be for deterministic multiplayer 
gaming.


Is there some central repository with links to the active 
projects? I'll try and wrap my head fully around the math before 
we get to that point though.


Re: @property Incorrectly Implemented?

2016-09-17 Thread Ethan Watson via Digitalmars-d

On Friday, 16 September 2016 at 20:52:37 UTC, John wrote:
Your comment was out of place, saying properties don't need to 
be changed is like saying @property shouldn't even be a D 
feature cause you can create the same functional program in 
C++, which does not have the property feature.


Stop reading rubbish that isn't there.

And pay attention. MSVC has the __declspec( property ) extension.

You also made a reference to C#, which doesn't even allow you 
take address of


And? Properties in C# are a massive example of a comparable 
feature where executed code is syntactically treated in some ways 
to a variable.


So I don't know what you mean by that's how I want to play, 
when you instigated said argument.


I indicated you're taking it personally. Which you are.

It's not really that important. What it allows is returning 
references. You can make a comparison to any other language 
that has properties it doesn't really matter. This is how D was 
implemented. If they wanted to be like every other language 
then it shouldn't have been allowed to even return a reference. 
But it is does, that's how it's implemented and odds are it 
probably won't change now to not allow it. D also has the "&" 
implemented, what I am discussing is whether it was implemented 
correctly or not. Honestly it is no implemented correctly. To 
the point I would actually rather they remove the functionality 
so that you can't take the address of a property. If they are 
not willing to change it to function in a different way.


Taking the address of a property and getting a function type is 
important.


Did you know that this C++ class:

class SomeObject
{
  virtual int getSomeValue() const;
  virtual int setSomeValue( int value );
};

Matches up exactly to this D class:

extern( C++ ) class SomeObject
{
  @property SomeValue() const;
  @property SomeValue( int value );
}

This has been brought up by someone else. I honestly don't 
understand why it's such a hard concept.


Because your understanding of the technical details is limited...

Maybe you don't come from C++ and thus don't use a language 
that provides a way to take the address of things.


...and you're assuming you know more than what I do on the 
subject.



That's why it keeps being brought up.


Calm down.

Anyways a bitfield can't actually represent a single, there's 
no type for a bit. The smallest type is a byte, which is 8 
bits. So even if it wasn't a property there's no way you can 
take the address of a bit. So that's the first issue, you are 
trying to use an example that doesn't make sense even outside 
the concept of properties. The second issue is, this is defined 
behavior. You can't take the address of a rvalue, there's an 
ideone link in my previous post show this if you missed it. So 
taking the address of a property would return an error if it 
didn't return a reference.


What you're suggesting, and why I brought up the example, is to 
change the implementation details of properties for *one* use 
case. This has wide ranging implications that you've clearly not 
thought of. Like if I was to take the address of that property 
for the purposes of exposing a function to C++. You want to make 
it so I don't get that function? Or that there's some extra 
convoluted method of getting it solely because you think a 
property should be something that it's not?



Well that's how it is currently implemented actually.

struct S
{
@property int prop() { return 0; }
}

writeln(typeof(S.prop).stringof) // prints "int", not 
"delegate"


Read further. I have suggested that the property resolution order 
gets changed so that this ambiguity goes away.



blah blah blah


Yeah I covered everything else already. Not helping your cause by 
stating your example that started this topic was *satirical*.


Re: @property Incorrectly Implemented?

2016-09-12 Thread Ethan Watson via Digitalmars-d

On Monday, 12 September 2016 at 09:25:40 UTC, Kagamin wrote:
You mean your serialization library will break if @property 
changes behavior?


Any serialisation library can break if a property is 
indistinguishable from an ordinary type, as a property is 
explicitly code that returns a value and faces all the allowances 
and restrictions that normal functions have.


In my case, it will break if this template fails:

template IsVariable( X... ) if ( X.length == 1 )
{
  static if( is( X[ 0 ] == void ) || is( typeof( X[ 0 ] ) == void 
) )

  {
enum IsVariable = false;
  }
  else static if ( !IsSomeType!( X[ 0 ] ) )
  {
static if( isSomeFunction!( X[ 0 ] ) )
{
  enum IsVariable = isFunctionPointer!( X[ 0 ] ) || 
isDelegate!( X[ 0 ] );

}
else
{
  enum IsVariable = is( typeof( X [ 0 ] ) )
  && !is( typeof( X [ 0 ] ) == void )
  && IsMutable!( typeof( X[ 0 ] ) );
}
  }
  else
  {
enum IsVariable = false;
  }
}


Re: @property Incorrectly Implemented?

2016-09-12 Thread Ethan Watson via Digitalmars-d

On Sunday, 11 September 2016 at 23:31:54 UTC, Timon Gehr wrote:

His property returns by ref.


Irrelevant for the implementation details of properties. Ref in 
that context specifies a function property that makes the 
property function return by ref (wrap your head around that one). 
That entire post went in to detail about why treating properties 
as the functions they are is correct.


You do realize that typeof(property) is the type of the return 
value, right? Also, it's easy. Add __traits(isVariable,...) or 
__traits(isProperty,...), or just use .tupleof. Furthermore you 
can even get the property accessor function overload set using 
(a hypothetical) __traits(getPropertyAccessors,...).


You are correct. typeof( __traits( getMember, Type, PropertyName 
) ) is the type of the return type of the function, since 
getMember forms a complete expression which evaluates down to the 
return type.


Note that all of the __traits( isFunction ) return true 
correctly on these things though. This is one of the checks I 
have to make when parsing over a class to correctly determine 
what is and isn't actually a variable. I've even wrapped it all 
up in a trait called IsVariable. The std library has traits for 
checking types but nothing that straight up tells you if 
something is a variable or not.


As such, who needs __traits( getPropertyAccessors ) when 
__traits( getOverloads ) already works?



[Commentary on example]


Actually, I take back what I said. Mostly because of typeof( t.x 
). The thing that needs fixing is the property evaluation order 
so that ambiguities like all of this don't exist.


Re: @property Incorrectly Implemented?

2016-09-11 Thread Ethan Watson via Digitalmars-d

On Sunday, 11 September 2016 at 07:19:54 UTC, John wrote:
You can't really take one sentence out of context, I didn't say 
it in the sense that it was completely broken to the point of 
being useless.


There's nothing out of context about it. Would it have made you 
feel better had I quoted your entire message knowing that I 
wouldn't have changed a word of the response?



But if that's how you want to play.

The part I'm asking to be changed, you probably didn't even 
ever use. C# is a managed language, I don't think you can even 
take the pointer of anything unless you enable the unsafe 
switch.


You're not showing a good grasp at all as to what a property is. 
In C# and in D, a property has *never* guaranteed the existence 
of a variable. In both cases, they allow syntactic sugar for 
letting the getter/setter pattern established by C++ look like 
variables.


This is important.

No, really.

Take std.bitmanip for an example of what I was talking about. It 
autogenerates properties for a bitfield. The types each property 
returns and lets you set are not at all indicative of the 
datatype underneath as it's literally just a bunch of bits. The 
property functions transform the data types given/return to/from 
a bitfield. What exactly do you suggest  return if it 
was to return a char starting at bit 13 of a bitfield?


But we can go one further. __traits( allMembers, Type ) and 
__traits( getMember, Type ). Let's say you're writing an 
auto-serialisation library (or take std.json as an example). 
Assuming a property is a stand-in for another variable then what 
happens there when you're checking for the type of a member is 
the delegate type, and later on you'll get the actual variable. 
Now change it so that the type of a property returns the actual 
type. Now you're serialising a piece of data twice.


But what if our @property function increments another variable 
inside a class whenever you access it? That's pretty dangerous if 
you start treating the property as an actual type instead of a 
function/delegate.


Thus, your example:

 // returns "ref int delegate()"
()   // ok returns "int*", but defeats purpose of 
@property
&(t.j = 10)  // shouldn't this return "ref int delegate(int)" 
?


First one I'd expect. Second one I'd expect. Third one I'd expect 
results in int*. You're getting the address of the results of the 
assign operation. Look at it this way: int val = (t.j = 10); 
You'd expect val and t.j to be 10, right? So why do you expect to 
get a ref int delegate(int) just because you ask for the address 
of it?


Like I said. Disagree. There's nothing that needs fixing here.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-10 Thread Ethan Watson via Digitalmars-d
On Saturday, 10 September 2016 at 08:26:44 UTC, rikki cattermole 
wrote:
Is there a good example library for this that does not involve 
a full blown (game)framework?


Not that I'm aware of.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-10 Thread Ethan Watson via Digitalmars-d
On Saturday, 10 September 2016 at 08:22:59 UTC, Ethan Watson 
wrote:
And if you exploit that correctly, this is one of those things 
that can increase boot times, actually.


*decrease boot times. Take that, edit button.



Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-10 Thread Ethan Watson via Digitalmars-d

On Saturday, 10 September 2016 at 05:56:55 UTC, Marco Leise wrote:
But what about the parts of the code that handle the game 
initialization before streaming starts? Is there no


  config = new GameConfig("settings.ini");

or

  db = new AssetDatabase("menu.pkg");

that perform I/O during construction and potentially display an 
exception error messages ?


Everything streams. No exceptions. The only file operations 
provided to game code at run time are asynchronous operations.


And if you exploit that correctly, this is one of those things 
that can increase boot times, actually. Create your 
config/database/whatever objects, request files, instead of 
initialising them all in order and slowing down because of 
synchronous IO they all go to sleep and streaming system can 
serve files up as quick as it gets them from disk.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-09 Thread Ethan Watson via Digitalmars-d

On Friday, 9 September 2016 at 12:16:00 UTC, Marco Leise wrote:
So when you have an object that reads state from a file, you 
first construct it and then call a member function 
"loadFromFile()" that may throw? For argument's sake let's take 
a *.bmp class. That one would not have a constructor with a 
filename? Or do you have such constructors and I/O exceptions 
are just logged and swallowed?


Remedy's Northlight engine is a streaming engine (that actually 
supports an open world, the legacy of Alan Wake development lives 
on). Thus, you need to follow some important rules. These are 
also pretty standard rules for game engines in general.


First and foremost, resources are processed offline to match the 
ideal binary format for the target platform. The industry has 
been using DXT textures for over a decade now, and they've been 
supported on consoles. The overwhelming majority of textures are 
thus baked in to such a format. Whichever format is chosen, on 
disk the file will essentially represent the resource's final 
layout in memory.


Second, file loading. You can't just go loading files any old 
time you want in a streaming-based, or even just straight up 
multithreaded, engine if you expect to keep within performance 
targets and not lock up every thread you've created. They need 
scheduling. Thus, resource creation needs to go through several 
steps:


* Something requests a resource, goes to sleep
* File loader schedules appropriately, notifies on load complete
* Object gets resource load notification, does work to hook it up 
to whatever API needs it


Anything that can assert/throw an exception is not in a 
constructor in these phases. And as mentioned elsewhere, asserts 
and exceptions are defined out for a retail build. If there's a 
problem with the data, we expect to find it in development and 
ship a product that doesn't require constant validation.


Re: Templates are slow.

2016-09-08 Thread Ethan Watson via Digitalmars-d

On Thursday, 8 September 2016 at 19:17:42 UTC, Lewis wrote:
I can't help but wonder if there were some way to automatically 
cache templates instantiations between runs of dmd?


I'm running with Visual D, which has a "COMPILE ALL THE THINGS" 
mentality as the default. As part of the rapid iteration part of 
Binderoo, I plan on doing incremental linking.


Of course, if all template instantiations go in to one object 
file, that really ruins it. Each template instantiation going in 
to a separate object file will actually make life significantly 
easier, as each compile will have less output. The only time 
those template instantiations need to recompile is if the 
invoking module changes; the template's dependencies change; or 
the module the template lives in changes.


My opinion is that splitting up object files will do more to 
reduce compile time for me than anything else, the pipeline we 
had for Quantum Break was to compile and link in separate steps 
so it's not much effort at all for me to keep that idea running 
in Binderoo and make it incrementally link. But I don't know the 
DMD code and I'm not a compiler writer, so I cannot say that 
authoritatively. It sounds very reasonable to me at least.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d
On Thursday, 8 September 2016 at 12:32:44 UTC, Andrei 
Alexandrescu wrote:
One thing we could look at is allow only CTFEable default 
constructors.


Wouldn't work in my case where I need to call a dynamically 
imported extern( C++ ) function to correctly construct an object.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d

On Thursday, 8 September 2016 at 11:26:22 UTC, Ethan Watson wrote:

Being D though. Destructors can be contracted, yeah?


Tested. Confirmed.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d
On Thursday, 8 September 2016 at 11:18:12 UTC, Walter Bright 
wrote:
The thing is, the 'destroy()' function is going to swamp any 
extra clock cycle, as will a virtual lookup and dereference.


Assume destroy() is a more trivial function then. The point is 
that if you put more than two branches in a 64-byte cacheline on 
that processor, things get significantly slower and the loop 
iteration itself becomes a hotspot.


Being D though. Destructors can be contracted, yeah? Because the 
way we operate is that we compile out all those validation checks 
for a retail release and assume everything works. Checking for 
the validity of the pointer in an in block would be perfect for 
that.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d

On Thursday, 8 September 2016 at 10:36:22 UTC, Dicebot wrote:
As a workaround I sincerely believe explicit 'create' (with 
forged mangling if needed) is better. It provides exactly the 
same functionality without tricking the developet into 
expecting more by confusion of the syntax similarity.


If I was to enforce a programming standard with static opCall(). 
The code for instantiating the Mutex example would look like:


Mutex foo = Mutex();

Later on down the track, behind the scenes when default 
constructors work for C++ types I remove the static opCall() 
implementation and replace it with default constructors. Right 
now, Mutex() without static opCall() just gives me the .init. 
With the static opCall(), I can construct it. With a default 
constructor?


I suppose that'd depend on future decisions that haven't been 
made yet. In C++ Mutex() is meant to invoke the zero initialiser. 
It's effectively the opposite in D when using static opCall(). 
Which one would be the correct way to default construct a class? 
We'll find out I suppose.


Either way, assuming the default constructor will be called 
regardless of if it's foo = Mutex; or foo = Mutex();, using 
static opCall() will cut down on future maintenance work.


We're going to disagree on this one, basically. I'm designing 
this system for people who don't want to have to remember to call 
fancy create functions.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d

On Thursday, 8 September 2016 at 09:33:01 UTC, Dicebot wrote:
Instead, it would be much more constructive (pun unintended) to 
focus on language changes to extern(c++) class bindings to make 
them suitable for the task - those won't affect anyone but C++ 
interop users.


I agree in principle, but it doesn't help me right now. It's 
holding up my work, which means it's costing someone money. 
Workarounds will have to suffice until the language can be 
updated.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d
On Wednesday, 7 September 2016 at 22:52:04 UTC, Walter Bright 
wrote:

Is:

if (resource != null)
resource.destroy();

v.s.:

resource.destroy();

so onerous? It's one TST/JNE pair for a value loaded into a 
register anyway.


This one has performance implications for game developers. The 
branch predictor in the CPU used for the Xbox One and the PS4 
isn't the greatest. If, for example, that destructor gets inlined 
and you're iterating over a range of resources and the destroy 
method is virtual, there's a good chance you will invoke the 
wrath of the dense branch predictor. You don't want to deal with 
the dense branch predictor.


http://www.agner.org/optimize/microarchitecture.pdf section 3.13 
has a bit more info on the branch predictor. Desktop Intel CPUs 
tend to hide performance problems like this thanks to their 
far-higher-quality branch predictors. Both chips gain benefits 
from sorting to how you expect the branch predictor to work, but 
there's a lot of code in a game codebase that isn't that low 
level.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-08 Thread Ethan Watson via Digitalmars-d
On Wednesday, 7 September 2016 at 21:05:32 UTC, Walter Bright 
wrote:
5. In my not-so-humble opinion, construction should never fail 
and all constructors should be nothrow, but I understand that 
is a minority viewpoint


100% agree there. I can't think of any class in our C++ codebase 
that fails construction, and it's a pretty common rule in the 
games industry to not assert/throw exceptions during construction.


Of course, with Binderoo being open sourced, I can't guarantee 
any of my end users will be just as disciplined.


Re: Templates are slow.

2016-09-08 Thread Ethan Watson via Digitalmars-d

On Thursday, 8 September 2016 at 05:02:38 UTC, Stefan Koch wrote:
I have just hit a barrier trying to optimize the compile-time 
in binderoo.


I did a double take when Stefan told me the representative sample 
code I gave him to run with Binderoo instantiated ~20,000 
templates and resulted in ~10,000,000 hash map look ups inside 
the compiler.


I can certainly write it to be more optimised, but one of the 
goals I have is to make the codebase human readable so that it's 
not just Manu and myself that can understand the code. As a 
result, I figure this could be representative of how an ordinary 
user would write templated code.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-07 Thread Ethan Watson via Digitalmars-d
On Wednesday, 7 September 2016 at 12:14:46 UTC, rikki cattermole 
wrote:

http://dlang.org/phobos/std_typecons.html#.scoped


This is the kind of hackaround I'd need to do if it were a 
class... And it would require more hacking around than the 
standard library supports. And it's a spiraling-out-of-control 
hack, which would effectively mean every C++ matching class will 
need to define a class and then an alias with the scoped type, 
and then that means the pattern matching I've been creating for 
function linkups won't work any more...


static opCall() and a static alloc function for allocating on the 
heap are still looking like the simplest options here.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-07 Thread Ethan Watson via Digitalmars-d
On Wednesday, 7 September 2016 at 12:09:21 UTC, Ethan Watson 
wrote:
This might actually get me what I want. I'll have to play 
around with it and see.


"Scope classes have been recommended for deprecation."

"A scope class reference can only appear as a function local 
variable."


So that's two nopes right there.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-07 Thread Ethan Watson via Digitalmars-d

On Wednesday, 7 September 2016 at 11:19:46 UTC, Dicebot wrote:

Is using svope class out of the question?


This might actually get me what I want. I'll have to play around 
with it and see.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-07 Thread Ethan Watson via Digitalmars-d

On Wednesday, 7 September 2016 at 11:42:40 UTC, Dicebot wrote:

If it is so, I'd call it a major extern(c++) bug.


The documentation seems to be correct. I can't extern( C++, class 
) or extern( C++, struct ) on an object, even in DMD 
2.071.2-beta3.


But ignoring that. My first member is offset by 8 bytes, even in 
an extern( C++ ) class. I assume it's just blindly sticking a 
vtable in there regardless of if I actually define virtual 
functions or not.


But regardless. Making it a class is still a bad idea since in 
this exact example it needs to exist on the stack/within an 
objects scope, which means you then need to further hack around 
with emplacement and wrappers and blah.


Binary matching, non-trivial constructors, and treating C++ 
objects like the value types they are will be required to make 
Binderoo work effortlessly. I've got two out of three of those. 
Not having any one of those is something of a deal breaker unless 
I get an effective workaround.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-07 Thread Ethan Watson via Digitalmars-d

On Tuesday, 6 September 2016 at 14:49:20 UTC, Ethan Watson wrote:

this( void* pArg = null );


Also doesn't work: this( Args... )( Args args ) if( Args.length 
== 0 )


Just for funsies I tried making my Mutex a class for the purpose 
of embedding it manually in a struct. But thanks to all classes 
inheriting from Object there's 16 bytes at the front of the class 
that I don't want (64-bit build, it's 8 bytes in 32-bit builds 
but we're never going back to 32-bit). So that's very definitely 
out of the question.


static opCall() seems to be the only way to do this then. I can 
autogenerate it for any C++ bound class. But it's inadequate. It 
leaves room for user error when instantiating any C++ object in 
D. It's also another thing that C++ programmers need to be 
thoroughly educated about as Type() in C++11 calls the zero 
initializer, but in D it's effectively the opposite semantics.


Re: @property Incorrectly Implemented?

2016-09-07 Thread Ethan Watson via Digitalmars-d

On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:

It would be nice to get this behavior fixed.


Disagree. I've used properties before in C# to transform to and 
from data sets required for network multiplayer. It works 
functionally the same way in D. Behaviour is as I would expect 
for the wider implications of how properties can work.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-06 Thread Ethan Watson via Digitalmars-d

On Tuesday, 6 September 2016 at 13:44:37 UTC, Ethan Watson wrote:

Suggestions?


Forgot to mention in OP that I had tried this( void* pArg = null 
); to no avail:


mutex.d(19): Deprecation: constructor mutex.Mutex.this all 
parameters have default arguments, but structs cannot have 
default constructors.


It's deprecated and the constructor doesn't get called. So no 
egregious sploits for me.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-06 Thread Ethan Watson via Digitalmars-d
On Tuesday, 6 September 2016 at 14:27:49 UTC, Lodovico Giaretta 
wrote:
That's because it doesn't initialize (with static opCall) the 
fields of SomeOtherClass, right? I guess that could be solved 
once and for all with some template magic of the binding system.


Correct for the first part. The second part... not so much. Being 
all value types, there's nothing stopping you instantiating the 
example Mutex on the stack in a function in D - and no way of 
enforcing the user to go through a custom construction path 
either.


Re: Struct default constructor - need some kind of solution for C++ interop

2016-09-06 Thread Ethan Watson via Digitalmars-d
On Tuesday, 6 September 2016 at 13:57:27 UTC, Lodovico Giaretta 
wrote:
Of course I don't know which level of usability you want to 
achieve, but I think that in this case your bind system, when 
binding a default ctor, could use @disable this() and define a 
factory method (do static opCall work?) that calls the C++ ctor.


static opCall doesn't work for the SomeOtherClass example listed 
in OP. @disable this() will hide the static opCall and the 
compiler will throw an error.


Somewhat related: googling "factory method dlang" doesn't provide 
any kind of clarity on what exactly is a factory method. 
Documentation for factory methods/functions could probably be 
improved on this front.


Struct default constructor - need some kind of solution for C++ interop

2016-09-06 Thread Ethan Watson via Digitalmars-d
Alright, so now I've definitely come up across something with 
Binderoo that has no easy solution.


For the sake of this example, I'm going to use the class I'm 
binary-matching with a C++ class and importing functionality with 
C++ function pointers to create a 100% functional match - our 
Mutex class. It doesn't have to be a mutex, it just needs to be 
any C++ class where a default constructor is non-trivial.


In C++, it looks much like what you'd expect:

class Mutex
{
public:
  Mutex();
  ~Mutex();
  void lock();
  bool tryLock();
  void unlock();

private:
  CRITICAL_SECTION  m_criticalSection;
};

Cool. Those functions call the exact library functions you'd 
expect, the constructor does an InitializeCriticalSection and the 
destructor does a DeleteCriticalSection.


Now, with Binderoo aiming to provide complete C++ matching to the 
point where it doesn't matter whether a class was allocated in 
C++ or D, this means I've chosen to make every C++-matching class 
a value type rather than a reference type. The reasoning is 
pretty simple:


class SomeOtherClass
{
private:
  SomeVitalObject m_object;
  Mutex   m_mutex;
};

This is a pretty common pattern. Other C++ classes will embed 
mutex instances inside them. A reference type for matching in 
this case is right out of the question. Which then leads to a 
major conundrum - default constructing this object in D.


D structs have initialisers, but you're only allowed constructors 
if you pass arguments. With a Binderoo matching struct 
declaration, it would basically look like this:


struct Mutex
{
  @BindConstructor void __ctor();
  @BindDestructor void __dtor();

  @BindMethod void lock();
  @BindMethod bool tryLock();
  @BindMethod void unlock();

  private CRITICAL_SECTION m_criticalSection;
}

After mixin expansion, it would look come out looking something 
like this:


struct Mutex
{
  pragma( inline ) this() { __methodTable.function0(); }
  pragma( inline ) ~this() { __methodTable.function1(); }

  pragma( inline ) void lock() { __methodTable.function2(); }
  pragma( inline ) bool tryLock() { return 
__methodTable.function3(); }

  pragma( inline ) void unlock() { __methodTable.function4(); }

  private CRITICAL_SECTION m_criticalSection;
}

(Imagine __methodTable is a gshared object with the relevant 
function pointers imported from C++.)


Of course, it won't compile. this() is not allowed for obvious 
reasons. But in this case, we need to call a corresponding 
non-trivial constructor in C++ code to get the functionality 
match.


Of course, given the simplicity of the class, I don't need to 
import C++ code to provide exact functionality at all. But I 
still need to call InitializeCriticalSection somehow whenever 
it's instantiated anywhere. This pattern of non-trivial default 
constructors is certainly not limited to mutexes, not in our 
codebase or wider C++ practices at all.


So now I'm in a bind. This is one struct I need to construct 
uniquely every time. And I also need to keep the usability up to 
not require calling some other function since this is matching a 
C++ class's functionality, including its ability to instantiate 
anywhere.


Suggestions?


Re: Taking pipeline processing to the next level

2016-09-05 Thread Ethan Watson via Digitalmars-d
On Monday, 5 September 2016 at 08:21:53 UTC, Andrei Alexandrescu 
wrote:
What are the benchmarks and the numbers? What loss are you 
looking at? -- Andrei


Just looking at the example, and referencing the map code in 
std.algorithm.iteration, I can see multiple function calls 
instead of one thanks to every indexing of the new map doing a 
transformation instead of caching it. I'm not sure if the lambda 
declaration there will result in the argument being taken by ref 
or by value, but let's assume by value for the sake of argument. 
Depending on if it's taking by value a reference or a value type, 
that could either be a cheap function call or an expensive one.


But even if it took it by reference, it's still a function call. 
Function calls are generally The Devil(TM) in a gaming 
environment. The less you can make, the better.


Random aside: There are streaming store instructions available to 
me on x86 platforms so that I don't have to wait for the 
destination to hit L1 cache before writing. The pattern Manu 
talks about with a batching function can better exploit this. But 
I imagine copy could also take advantage of this when dealing 
with value types.


Re: ADL

2016-09-05 Thread Ethan Watson via Digitalmars-d

On Monday, 5 September 2016 at 01:00:26 UTC, Walter Bright wrote:

What about using this template?


Sure, it'll work assuming the module imports all its symbols 
publically, but it's still not as usable as it should be. I still 
need to invoke it for a number of things, including member 
variable types.


If the member variable is templated, I need to analyse the 
template arguments for types to import them too.


If it is a function, I need to treat each argument as I treat a 
member variable.


I started a thread the other day that touches on another problem 
I have which this template won't solve: 
https://forum.dlang.org/thread/wggldyzrbwjboibin...@forum.dlang.org


At least in my use cases, it comes down to the template instance 
not inheriting the visibility of symbols from its template 
parameters. Which leads to these workarounds.


We're aiming for the goal of sub-second compile and reload times 
for rapid iteration, both with normal code and scripter code. 
Anything I have to do through templates and CTFE slows compile 
times down, in some cases significantly.


Re: ADL

2016-09-04 Thread Ethan Watson via Digitalmars-d
On Saturday, 3 September 2016 at 01:09:18 UTC, Walter Bright 
wrote:

Fourth solution:

module myalgorithm;

void test(T)(T t)
{
import std.traits;
mixin("import " ~ std.traits.moduleName!T ~ ";");
mixin("alias M = " ~ std.traits.moduleName!T ~ ";");
// The above could be encapsulated into an eponymous 
template

// that takes T as a parameter and returns the alias

M.f(t);
}


Chipping in to say that I currently do something this with 
Binderoo templates... and it sucks.


https://github.com/Remedy-Entertainment/binderoo/blob/master/binderoo_client/d/src/binderoo/variabledescriptor.d

One example is in there, the VariableDescriptors eponymous 
template, where a template that collects every member variable of 
an object has to mix in the module names of each encountered 
member variable type to stop the compiler complaining about 
module visibility. So I'm doing the double whammy of taxing the 
template expansion engine and the CTFE engine. It could be that 
switching it to a mixin template (and working out someway to make 
it as usable as eponymous templates) will solve the problem - but 
the way this codebase is going it's going to mean every template 
needs to be a mixin.


Surely the base template system can be more flexible than this?


Re: Quality of errors in DMD

2016-09-04 Thread Ethan Watson via Digitalmars-d

On Sunday, 4 September 2016 at 10:33:44 UTC, Walter Bright wrote:
As I mentioned before, assert failures are usually the result 
of the last edit one did. The problem is already narrowed down.


I got the error at the start of the thread because I added a 
variable to a class. The class is having two mixins applied to 
it, which invoke templated code themselves. I knew that 
commenting out this variable would work around the problem - but 
it very definitely was not a good workaround as this struct is 
being used to match a C++ struct. Which meant I had to fumble my 
way through multiple mixins and templates working out what had 
actually caused the problem.


Saying an assert is the result of the last thing you did, sure, 
it tends to be correct. But it's not as simple in D as it was in 
the C/early C++ days, especially when mixins are already a pain 
to debug.


Re: Quality of errors in DMD

2016-09-04 Thread Ethan Watson via Digitalmars-d

On Sunday, 4 September 2016 at 05:13:49 UTC, Walter Bright wrote:
If you're willing to look at the file/line of where the assert 
tripped, I don't see how a message would save any time at all.


The level builders at Remedy are going to be using D as a 
scripting language. If they get an error like this, they can't be 
expected to open a compiler's source code. Especially since as a 
part of the tool chain I won't be shipping it out to them.


Re: Quality of errors in DMD

2016-09-04 Thread Ethan Watson via Digitalmars-d

On Sunday, 4 September 2016 at 00:09:50 UTC, Stefan Koch wrote:
Perhaps the best error message would be "Please post this as a 
bug to bugzilla."


I'd say that's in addition to getting rid of assert(0), not 
instead of.


Re: Quality of errors in DMD

2016-09-04 Thread Ethan Watson via Digitalmars-d
On Saturday, 3 September 2016 at 22:53:25 UTC, Walter Bright 
wrote:
Adding more text to the assert message is not helpful to end 
users.


Really? I've highlighted several cases just in this one function 
in glue.c that would have saved me hours of time.


Re: Usability of "allMembers and derivedMembers traits now only return visible symbols"

2016-09-03 Thread Ethan Watson via Digitalmars-d
On Saturday, 3 September 2016 at 21:54:24 UTC, Jacob Carlborg 
wrote:
Here's the PR that introduced the change: 
https://github.com/dlang/dmd/pull/6078


I'm certainly not going to upgrade to the next DMD if this change 
is retained. allMembers not returning all members makes 
introspection entirely useless when it comes to Binderoo.


The wrong conclusions were made from that bug to begin with it 
seems. allMembers should return all members. getProtection should 
report on the protection of a symbol *regardless* of whether 
getMember will succeed or not (this is currently why I have my 
PrivacyOf workaround - to stop the compiler crashing when using a 
template instead of a mixin template to do introspection).


getMember itself, well, I'd honestly prefer if there was a way to 
get to members without having to correlate with .tupleof as it 
will simplify Binderoo code. The .tupleof method doesn't help me 
when it comes to introspecting private/protected functions for 
C++ binding.


Re: Quality of errors in DMD

2016-09-03 Thread Ethan Watson via Digitalmars-d
On Saturday, 3 September 2016 at 13:20:37 UTC, Adam D. Ruppe 
wrote:
Except that in the real world, it is an irrelevant distinction 
because you have stuff to do and can't afford to wait on the 
compiler team to actually fix the bug.


If nothing else, you'd like to know where it is so you can hack 
around the bug by changing your implementation. I'm sure every 
long time D programmer (and likely C++ if you've been in a long 
time, I have hit many bugs in g++ too) has hit a compiler bug 
and "fixed" it by using some different approach in their user 
code.


Exactly this. If a compiler bug stops someone from working in a 
production environment because there's no information about why 
the bug occured, the semantic difference between a compiler bug 
and a user code bug means precisely nothing to the end user. It 
does mean that they're losing hours of work while the problem is 
clumsily attempted to be diagnosed.


In the cases I've been bringing up here, it's all been user code 
that's been the problem *anyway*. Regardless of if the compiler 
author was expecting code to get to that point or not, erroring 
out with zero information is a bad user experience.


This also gets compounded in environments where you can't just 
grab the hottest DMD with a compiler bug fix. Before too long, 
our level builders will be using D as their scripting language. 
They need a stable base. We can't do something like upgrade a 
compiler during a milestone week, so upgrades will be scheduled 
(I'm planning on going with even-numbered releases). A fix for 
the compiler bug is no good if I can't ship it out for months. 
The only way to go there is to implement workarounds until such 
time an upgrade is feasible.


(Side note: There's zero chance of me upgrading to the next DMD 
if it retains the altered allMembers functionality)


These kinds of problems are likely to be compounded when D 
reaches critical mass. It's all well and good to tell people in 
the enthusiast community "Run  to get a repro case and make a 
bug". If a problem can't be easily googlable or understandable 
from the error reporting, then that's a turn off for a wider 
audience.


Re: Quality of errors in DMD

2016-09-03 Thread Ethan Watson via Digitalmars-d

On Friday, 2 September 2016 at 21:52:57 UTC, Walter Bright wrote:
I understand your concern, and that's why we put a priority on 
fixing asserts that are submitted to bugzilla. But without a 
bug report, we are completely dead in the water in fixing it. 
It is supposed to never happen, that is why we cannot fix them 
in advance.


We have a rule in our codebase, and it's been the same in every 
codebase I've worked in professionally. If you throw an assert, 
you have to give a reason and useful information in the assert.


Thus, an error in code that looks like:

assert(0);

Makes no sense to me when in this case it could have been:

fatal_error("Invalid type (from %d to %s)", tx->ty, 
tx->toChars());


The quality of error reporting has immediately increased. And it 
would require the creation of a fatal_error macro that does an 
assert. But now I'm not scratching my head wondering what went 
wrong in the compiler.


Browsing through that function, I can also see another assert 
that doesn't let you use vector types unless you're running a 
64-bit build or are on OSX. It doesn't tell me that through an 
error message. I had to look at the source code to work it out. 
fatal_error("Vector types unavailable on the target platform"); 
and someone's day was made better. And then a couple of lines 
above that, another assert(0). fatal_error("Invalid vector type 
%s", tx->toChars()); and someone can deal with the unexpected.


If I have to open up the compiler's source to get an idea of what 
I'm doing wrong, that's a bad user experience. And why I want a 
discussion about this. Not to whinge, not to get a bug fix. But 
to highlight that assert(0) is a bad pattern and there should be 
a discussion about changing the usage of asserts inside DMD.


Re: Quality of errors in DMD

2016-09-02 Thread Ethan Watson via Digitalmars-d

On Friday, 2 September 2016 at 21:16:02 UTC, Walter Bright wrote:
assert()s are there to check that impossible situations in the 
compiler don't actually happen. They are not for diagnosing 
errors in user code.


If a user sees an assert, it is a compiler bug and hopefully 
he'll submit a bug report for it in bugzilla. There aren't many 
open assert bugs in bugzilla because we usually put a priority 
on fixing them.


You know, I'd love to submit a bug about it. But after actually 
working out the problem without the compiler's help, I can't get 
a minimal enough test case to submit a bug with. I'll try it with 
Dustmite. But in this case, there's debug code there to spit out 
the information it has. And probably a stack to give it context.


This is legitimately the kind of stuff that drives an average 
user away from a language. I knew that commenting out one 
template invocation fixed my code, but not how to fix my template 
without a bunch of pain-staking removal and experimentation. Call 
it what you want, but that's a bad user experience.


Quality of errors in DMD

2016-09-02 Thread Ethan Watson via Digitalmars-d
Can we have a serious discussion in here about the quality of DMD 
errors?


I've been alternately a dog chasing its own tail, and a dog 
barking at a fire hydrant, chasing down errors deep in templated 
and mixin code over the last day. This has resulted in manually 
reducing templates and mixins by hand until I get to the root of 
the problem, which then results in submitting a bug and devising 
an ugly workaround.


And then I get this one in some code:

Assertion failure: '0' on line 1492 in file 'glue.c'

The problem ended up being that a symbol tucked away in a 
template that itself was tucked away in a template was undefined, 
but it couldn't tell me that. Rather, it just assert(0)'d and 
terminated. Rather less helpfully, the only meaningful 
information it could give me at the assert point (Could it add to 
it further down the stack? Maybe?) was defined out because DMD 
wasn't in a debug build.


Honestly, I find stuff like this in a compiler unacceptable. 
Using assert(0) as shorthand for an unexpected error is all fine 
and dandy until you put your product in the hands of the masses 
and they expect your program to at least give you some idea of 
what was going wrong rather than just crashing out in flames.


So just for fun, I searched DMD for all instances of assert(0) in 
the code base.


830 matches in DMD 2.070.2.

That's 830 possible places where the compiler will give the user 
virtually no help to track down what (if anything) they did wrong.


DMD certainly isn't the only compiler guilty of this. The .NET 
compiler gives precisely no useful information if it encounters 
SSE types in C++ headers for example. But compared to MSVC, I've 
found the error reporting of DMD to be severely lacking. In most 
cases with MSVC, I have an error code that I can google for which 
is (sometimes) thoroughly documented. And thanks to being a 
widely used product, Stack Overflow usually gives me results that 
I can use in my sleuthing.


I know I'm also seeing more errors than most because I'm doing 
the kind of code most people don't do. But I'm certainly of the 
opinion that searching for a compiler error code is far easier 
than trying to trick google in to matching the text of my error 
message.


Re: Fallback 'catch-all' template functions

2016-09-01 Thread Ethan Watson via Digitalmars-d
On Thursday, 1 September 2016 at 11:01:28 UTC, Dominikus Dittes 
Scherkl wrote:
Ok, that may be fine, until you reach the point with the 
fallback version: if after that point someone "drops in" a new 
version, he silently changes the behavior of the function, 
because he "steals" some type which used to use the fallback 
version.


I don't see how that can be considered anything other than 
"expected behaviour" and thus ensure your design takes this in to 
account. If you give your user the keys to the kingdom, you need 
to expect them to use it.


Re: Fallback 'catch-all' template functions

2016-09-01 Thread Ethan Watson via Digitalmars-d
On Thursday, 1 September 2016 at 10:43:50 UTC, Dominikus Dittes 
Scherkl wrote:
I have never seen what benefit could be gained from having 
overloads.


Oh, it's perfectly fine if you're not writing a library that's 
designed to allow user extension by going the "all in one" 
method. If you encourage your users to modify your function 
itself, they can no longer drop in a new version and have to do a 
merge.


Templates in general seem weak for libraries in D, which is a 
pain considering templates are one of the areas where the 
language otherwise excels.


Re: Fallback 'catch-all' template functions

2016-09-01 Thread Ethan Watson via Digitalmars-d

On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote:
I have a recurring problem where I need a fallback function 
like the bottom one, which should be used in lieu of a more 
precise match.


+1. I've already hit this a few times with Binderoo. I would have 
assumed that constraints are just another form of specialisation, 
but it requires me to be explicit with the base functionality.


  1   2   >