Re: Dealing with raw types as attributes
On Friday, 2 November 2018 at 04:18:47 UTC, Neia Neutuladh wrote: On Fri, 02 Nov 2018 04:01:00 +, Nicholas Wilson wrote: By noting that all (interesting for the purpose of UDA's i.e. not void) types have a .init or you could do static if (is(typeof(uda) == Foo) || is(uda == Foo)) Which, again, only tests for presence, when I want to check for presence *and* get the value, which should be Foo.init if the person supplied the raw type. template GetMeTheValue(value...) if(value.length == 1) { static if (is(typeof(value[0].init == value[0]) // A type enum GetMeTheValue = value[0].init; else enum GetMeTheValue = value[0]; } ... static if (is(typeof(GetMeTheValue!uda) == Foo)
Re: Dealing with raw types as attributes
On Fri, 02 Nov 2018 04:01:00 +, Nicholas Wilson wrote: > By noting that all (interesting for the purpose of UDA's i.e. not void) > types have a .init > > or you could do > > static if (is(typeof(uda) == Foo) || is(uda == Foo)) Which, again, only tests for presence, when I want to check for presence *and* get the value, which should be Foo.init if the person supplied the raw type.
Re: Dealing with raw types as attributes
On Friday, 2 November 2018 at 03:13:19 UTC, Neia Neutuladh wrote: On Fri, 02 Nov 2018 00:36:18 +, Nicholas Wilson wrote: What do you do to handle this? @Foo() int bar; instead of @Foo int bar; Right. And if you're offering a library with UDAs for other people to use? I mean I suppose if you really wanted to avoid the parentheses, you could do static foreach (uda; __traits(getAttributes, bar)) { static if (is(typeof(uda.init) == Foo) { pragma(msg, "bar is @Foo"); } } By noting that all (interesting for the purpose of UDA's i.e. not void) types have a .init or you could do static if (is(typeof(uda) == Foo) || is(uda == Foo))
Re: Dealing with raw types as attributes
On Fri, 02 Nov 2018 00:36:18 +, Nicholas Wilson wrote: >> What do you do to handle this? > > @Foo() int bar; > > instead of > > @Foo int bar; Right. And if you're offering a library with UDAs for other people to use?
Re: Removing the precision from double
On Thu, 01 Nov 2018 23:59:26 +, kerdemdemir wrote: > I am doing trading and super scared of suprices like mathematical errors > during the multiplications(or division 1/tickSize) since market will > reject my orders even if there is a small mistake. > > Is this safe? Or is there a better way of doing that ? tldr: consider using std.experimental.checkedint and highly granular units, like milli-cents. Also consider using a rational number library. Doubles aren't necessarily bad, but they'd concern me. # 1. Fixed precision The common way of working with sensitive financial stuff is fixed precision numbers. With fixed precision, if you can represent 0.0001 cents and you can represent ten billion dollars, you can represent ten billion dollars minus 0.0001 cents. This is not the case with single-precision floating point numbers: writeln(0.0001f); writefln("%20f", 10_000_000_000f); writefln("%20f", 10_000_000_000f - 0.0001f); prints: 0.0001 100.00 100.00 The problem with fixed precision is that you have to deal with overflow and underflow. Let's say you pick your unit as a milli-cent (0.001 cents, $0.1). This works okay...but if you're trying to assign a value to each CPU cycle, you'll run into integer underflow. Like $10/hour divided by CPU cycles per hour is going to be under 0.001 cents. And if you try inverting things to get cycles per dollar, you might end up with absurdly large numbers in the middle of your computation, and they might not fit into a single 64-bit integer. ## Fixed precision with Checked std.experimental.checkedint solves the overflow problem by turning it into an error. Or a warning, if you choose. It turns incorrect code from a silent error into a crash, which is a lot nicer than quietly turning a sale into a purchase. It doesn't solve the underflow problem. If you try dividing $100 by 37, you'll get 270270 milli-cents, losing a bit over a quarter milli-cent, and you won't be notified. If that's deep in the middle of a complex calculation, errors like that can add up. In practice, adding six decimal places over what you actually need will probably be good enough...but you'll never know for certain. # Floating point numbers Floating point numbers fix the underflow and overflow problems by being approximate. You can get numbers up to 10^38 on a 32-bit float, but that really represents a large range of numbers near 10^38. **That said**, a double can precisely represent any integer up to about 2^53. So if you were going to use milli-cents and never needed to represent a value over one quadrillion, you could just use doubles. It would probably be easier. The problem is that you won't know when you go outside that range and start getting approximate values. # Rational numbers A rational number can precisely represent the ratio between two integers. If you're using rational numbers to represent dollars, you can represent a third of a dollar exactly. $100 / 37 is stored as 100/37, not as something close to, but not exactly equal to, 2.702 repeating. You can still get overflow, so you'll want to use std.experimental.checkedint as the numerator and denominator type for the rational number. Also, every bit of precision you add to the denominator sacrifices a bit of range. So a Rational!(Checked!(long, Throw)) can precisely represent 1/(2^63), but it can't add that number to 10. Manual rounding can help there.
Re: Dealing with raw types as attributes
On Thursday, 1 November 2018 at 16:14:45 UTC, Neia Neutuladh wrote: The spec says that a user-defined attribute must be an expression, but DMD accepts a wide range of things as UDAs: Indeed UDA are odd beasts: https://issues.dlang.org/show_bug.cgi?id=19127 What do you do to handle this? @Foo() int bar; instead of @Foo int bar; https://run.dlang.io/is/3USj6h
Re: Removing the precision from double
On Thursday, 1 November 2018 at 23:59:26 UTC, kerdemdemir wrote: I have two numbers First The price = 0.0016123 Second Maximum allowed precision = 0.0001(it can be only 0.001, 0.0001, 0.1, ..., 0.01 bunch of zeros and than a one that is it) Anything more precise than the allow precision should truncated. So in this case 0.0016123 should turn into 0.0016. I coded this which in my tests have no problem : double NormalizeThePrice( double price, double tickSize) { import std.math : floor; double inverseTickSize = 1.0/tickSize; return floor(price * inverseTickSize) * tickSize; } writeln(NormalizeThePrice(0.0016123, 0.0001)); Returns 1.6e-07 as excepted. I am doing trading and super scared of suprices like mathematical errors during the multiplications(or division 1/tickSize) since market will reject my orders even if there is a small mistake. Is this safe? Or is there a better way of doing that ? Erdemdem the function you does what you describe is called quantize[1]. However be warned that dealing with money as a floating point type is generally not a great idea. Precision losses (especially when working with ranges like 10^-7) and NaNs (Sociomantic's $9T bug, yes 9T thats what lround(NaN) gives) [2] are thing you _must_ account for. I _think_ the accepted way of dealing with it is to use an (non overflowing[3]!) integer representing the lowest amount (e.g. 1 cent), and deal in integer multiples of that. [1]: https://dlang.org/phobos/std_math.html#.quantize [2]: https://dconf.org/2016/talks/clugston.html [3]: https://dlang.org/phobos/core_checkedint.html
Re: Removing the precision from double
On Thu, Nov 01, 2018 at 11:59:26PM +, kerdemdemir via Digitalmars-d-learn wrote: > I have two numbers > > First The price = 0.0016123 > Second Maximum allowed precision = 0.0001(it can be only 0.001, > 0.0001, 0.1, ..., 0.01 bunch of zeros and than a one that > is it) Beware! Floating-point values in D are stored as binary, and certain decimal fractions cannot be stored exactly in binary. Because of that, it's generally better to consider using a decimal arithmetic library for representing monetary amounts, especially when you have precise requirements on the number of decimal places a number has to fit into. IEEE floating-point has some quirks that can give you a nightmare of a debugging session if you're expecting them to behave exactly like decimals. [...] > I am doing trading and super scared of suprices like mathematical > errors during the multiplications(or division 1/tickSize) since market > will reject my orders even if there is a small mistake. > > Is this safe? Or is there a better way of doing that ? [...] You probably want to be using a decimal number library instead of floating-point. The mismatch between the binary representation and the decimal representation will give you a headache especially if you're dealing with financial transactions that expects certain behaviours of the decimal digits, which the binary digits cannot exactly match. Either that, or store your numbers as fixed-point integers (e.g., as an int or long with the rightmost n digits interpreted to be the fractional part -- if you go this route you'd want to encapsulate the arithmetic in a struct with overloaded operators so that it's more convenient to use, and you'll want to be careful of arithmetic overflows). Using IEEE floating-point for financial computations is tricky business, and you need to fully understand what you're doing and exactly how IEEE floats work, in order not to get yourself into trouble at some point. T -- We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true. -- Robert Wilensk
Removing the precision from double
I have two numbers First The price = 0.0016123 Second Maximum allowed precision = 0.0001(it can be only 0.001, 0.0001, 0.1, ..., 0.01 bunch of zeros and than a one that is it) Anything more precise than the allow precision should truncated. So in this case 0.0016123 should turn into 0.0016. I coded this which in my tests have no problem : double NormalizeThePrice( double price, double tickSize) { import std.math : floor; double inverseTickSize = 1.0/tickSize; return floor(price * inverseTickSize) * tickSize; } writeln(NormalizeThePrice(0.0016123, 0.0001)); Returns 1.6e-07 as excepted. I am doing trading and super scared of suprices like mathematical errors during the multiplications(or division 1/tickSize) since market will reject my orders even if there is a small mistake. Is this safe? Or is there a better way of doing that ? Erdemdem
Re: Dealing with raw types as attributes
On Thursday, 1 November 2018 at 20:33:10 UTC, Neia Neutuladh wrote: On Thu, 01 Nov 2018 20:01:51 +, Stanislav Blinov wrote: Check if an UDA is a type?.. As in, not just `is(uda == Foo)`, but simply `is(uda)`: Which works, but generally makes things more complex in code that's already pretty deeply nested. It's also something I have to worry about every time I do the static foreach to get UDAs, in the cases where that's more than once. Yes, it does :( I could use a customized version of [getUDAs] that replaces @Type with @Type.init, and that's a reasonable choice... That can't be generic, as you can have UDAs that don't have an .init: enum XXX; @XXX int bar; static foreach (uda; __traits(getAttributes, bar)) { static if (is(uda == XXX)) { pragma(msg, "bar is XXX"); } } ...but so long as you can live without such UDAs, I guess it could work.
Re: Dealing with raw types as attributes
On Thu, 01 Nov 2018 20:01:51 +, Stanislav Blinov wrote: > Check if an UDA is a type?.. As in, not just `is(uda == Foo)`, > but simply `is(uda)`: Which works, but generally makes things more complex in code that's already pretty deeply nested. It's also something I have to worry about every time I do the static foreach to get UDAs, in the cases where that's more than once.
Re: Dealing with raw types as attributes
On Thu, 01 Nov 2018 11:35:27 -0700, Ali Çehreli wrote: > On 11/01/2018 09:14 AM, Neia Neutuladh wrote: >> The spec says that a user-defined attribute must be an expression, but >> DMD accepts a wide range of things as UDAs: >> >>struct Foo { string name = "unknown"; } >>@Foo int bar; >> >> `bar` has the *type* Foo as an attribute. It's not an *instance* of >> Foo. So if I try to look at the UDAs: > > That would work with hasUDA(). I have an example here: > >http://ddili.org/ders/d.en/uda.html That lets me test for presence, nothing more. While that's useful, I usually have a UDA struct whose fields I need to access. std.traits.getUDAs doesn't hide the difference between @Foo and @Foo(), so that's also not an option. I could use a customized version of that that replaces @Type with @Type.init, and that's a reasonable choice when I know other people aren't going to deal with that annotation type.
Re: Dealing with raw types as attributes
On Thursday, 1 November 2018 at 16:14:45 UTC, Neia Neutuladh wrote: The spec says that a user-defined attribute must be an expression, but DMD accepts a wide range of things as UDAs: struct Foo { string name = "unknown"; } @Foo int bar; `bar` has the *type* Foo as an attribute. It's not an *instance* of Foo. So if I try to look at the UDAs: static foreach (uda; __traits(getAttributes, bar)) { static if (is(typeof(uda) == Foo)) { pragma(msg, "bar is @Foo"); } } That just doesn't work; typeof(Foo) isn't anything, so is(typeof(Foo) == Foo) is false. I can change my code to read `static if (is(uda == Foo))`. But that obviously fails: @Foo("customName") int bar2; What do you do to handle this? Check if an UDA is a type?.. As in, not just `is(uda == Foo)`, but simply `is(uda)`: ``` struct Foo { string name = "unknown"; } @Foo @string @Foo("hello") int bar; static foreach (uda; __traits(getAttributes, bar)) { static if (is(uda)) { // if `uda` is a type... static if (is(uda == Foo)) { pragma(msg, "bar is @Foo!!!"); } else { pragma(msg, "bar is "~uda.stringof); } } else { // if `uda` is not a type... pragma(msg, "bar is "~uda.stringof); } } ```
Re: Dealing with raw types as attributes
On 11/01/2018 09:14 AM, Neia Neutuladh wrote: The spec says that a user-defined attribute must be an expression, but DMD accepts a wide range of things as UDAs: struct Foo { string name = "unknown"; } @Foo int bar; `bar` has the *type* Foo as an attribute. It's not an *instance* of Foo. So if I try to look at the UDAs: That would work with hasUDA(). I have an example here: http://ddili.org/ders/d.en/uda.html Ali
Dealing with raw types as attributes
The spec says that a user-defined attribute must be an expression, but DMD accepts a wide range of things as UDAs: struct Foo { string name = "unknown"; } @Foo int bar; `bar` has the *type* Foo as an attribute. It's not an *instance* of Foo. So if I try to look at the UDAs: static foreach (uda; __traits(getAttributes, bar)) { static if (is(typeof(uda) == Foo)) { pragma(msg, "bar is @Foo"); } } That just doesn't work; typeof(Foo) isn't anything, so is(typeof(Foo) == Foo) is false. I can change my code to read `static if (is(uda == Foo))`. But that obviously fails: @Foo("customName") int bar2; What do you do to handle this? My current workaround is to make the attribute into a struct instance and use opCall in lieu of constructors: struct _Foo { string name; _Foo opCall(string name) { _Foo f; f.name = name; return f; } } enum _Foo Foo = _Foo.init; Now I can use `static if (is(typeof(uda) == _Foo))` and it always works. But are there better options? Any obvious flaws?
Re: Small or big dub packages
On Monday, 29 October 2018 at 11:31:55 UTC, Igor wrote: The way I see it the advantage of smaller packages is that users can pick and choose and and only have the code they really need in their project, but the con could become managing a lot of dependencies. Also I am not sure how compile time on clean project and previously compiled project would be affected. Pros: Users can pick exactly what they need. Encourages decoupling instead of too much cohesion. Less code to build and maintain. Less chances of breakage on upgrade since you depend on less. Improve build time since only modified sub-packages get rebuilt. Good for the ecosystem. Cons: More link-time operations when not using --combined, each sub-package is compiled at once. Too much sub-package can slow down builds. Possibly hitting more DUB edge cases (less the case since DUB has tests) Directory layout may need to change for proper VisualD support. On the DUB registry, sub-packages are less popular than "big" packages because less discoverable and for some reasons some people won't just pick a sub-package when there is a toplevel package.
Re: Profiling with DUB?
On Monday, 29 October 2018 at 10:14:23 UTC, Dukc wrote: I'm trying to profile my program, built like: dub build --build=profile When I run the program, where is the performance profile file supposed to appear? I can find nothing new in the program/project root directory. This happens regardless whether I compile with dmd or ldc2. If you want to use sampling profilers (like the free Intel Amplifier coming with System Studio) you can also use dub build -b release-debug And then check in your profiler.
Re: CT BitArray
On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote: Tell me which version are you using and I'll make it for you. By the way this is a really generous offer, thanks for being like that!
Re: CT BitArray
On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote: On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote: Currently, BitArray is not usable at compile time, so you cannot do ``` enum e = BitArray([1, 1, 1, 0]); ``` This gives /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code IIUC, that is because `bts` comes from core.bitop but no source code is there. I am guessing these are filled in by compiler intrinsics or the like, and they are unavailable at CT, correct? I suppose that alternative implementations of `btc`, `bts`, `btr`, `bsf` and `bt` could exist that do not use the runtime that could be used if(__ctfe) in the implementation of BitArray, that would make the above code work. Is this feasible? Is there precedent in phobos? Are there complications? Thanks! Oh that ... actually I can fix that with a small patch to dmd. Tell me which version are you using and I'll make it for you. Cheers, Stefan Thank you, Stefan. At the moment we are using latest stable dmd, v2.082.1. I expect to switch to ldc or gdc at a later time. I don't think we'll be patching the compiler, support in the mainline compilers would be much preferable. It is not a blocker either, we can wait as long as it takes and meanwhile use module level BitArrays like ``` immutable BitArray e; static this() { e = BitArray([1, 1, 1, 0]); } ``` It just seemed like a fixable limitation to me, hence my question here. Shall we start with a feature request? Bastiaan.
Re: Where do I learn to use GtkD
On Thu, 2018-11-01 at 03:46 +, helxi via Digitalmars-d-learn wrote: […] > > Why is that, if I may ask? Is it the licensing concerns? > As with any programming language or framework, the biggest driver of opinion tends to be the personal prejudices of those who shout loudest and longest. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part