Re: Range of n lines from stdin
On Friday, 27 December 2013 at 20:30:52 UTC, Ivan Kazmenko wrote: Hmm?.. From my experience, attempting to use a range in a wrong way usually results in a compilation error. For example, I can't do n.iota.map!(_ = readln).sort()) since MapResult isn't a random access range with swappable elements. I can instead do n.iota.map!(_ = readln).array().sort()) and it allocates an array and works as expected. So, how do I misuse that range? Yes, the idea is that ranges only present interfaces that make sense, so cases of misuse will result in a compilation error. However, hacks like using map with functions that ignore their argument(s) throws that out of the window: `r` in `auto r = n.iota.map!(_ = readln);` claims to support forward, bidirectional and random access (all read-only, as the argument function returns by value) as well as slicing, but none of these make any sense; all access primitives do exactly the same thing, with the result being different every time. Even the simplest invariants fail, such as `r.front == r.front`, and `popFront`, `popBack` and slicing only has a binary effect, whether or not the range is empty yet. Hmm. For example, that could be a RNG emitting (a range of) random numbers, then empty is always false. But we still want a new random number each time. Something like n.iota.map!(_ = uniform(0, 10)) That would only provide `n` random numbers, not an infinite number. All the random number generator types in `std.random` are infinite forward ranges of random numbers, which is completely fine. For any PRNG `r`, `r.front == r.front` is true, and remains the same number until `r.popFront()`, it correctly has no length and is always non-empty (infinite range), and `r.save` works correctly etc. So, something like n.iota.map !(_ = readln).writeln; is bad style but writeln (n.iota.map !(_ = readln)); better shows what's the main action? Makes sense for me. No, it has nothing to do with syntax. The two examples are completely equivalent, and the only problem is that it breaks the invariant that the result of map's transformation function should be derived from the arguments it was given. The fact that the transformation function is impure is not in itself a problem: pure functions can also ignore arguments, and impure functions can return consistent results while still being necessarily impure. Perhaps there's a wholly different way of thinking about this in which the first definition makes much more sense than then second one from the start. If so, please share it. All you have to do is look at the signature of the function, which is the primary part of its documentation: Repeat!T repeat(T)(T value); It takes one value of any type T, not a function pointer or delegate that returns T. Even if you give it a function pointer or delegate (which your example does not), it will simply repeat that function pointer or delegate, never calling it. As I already explained, `readln.repeat(n)` is just a different way of writing `readln().repeat(n)` which in turn is also equivalent to `repeat(readln(), n)`. This should make it perfectly clear what it does - `readln` is called and its return value is passed to `repeat`. Barring one relatively obscure exception[1], this is the only way to interpret the expression regardless of the signature of the function, as a consequence of basic languages rules common to the entire C family of programming languages. [1] ... in D we have something (slightly controversial) called the `lazy` parameter storage class, but when used, it is clearly visible in the signature of the function. http://dlang.org/function.html#parameters
Re: Ultra-pure map()?
On 12/27/2013 7:32 PM, Marco Leise wrote: [...] Side effects and altering the input object itself makes me want to pull out my crucifix. You shall not have impurity in your functional style code! Why not? There are many impure functional languages, and most non-functional languages that allow functional style allow mutation. OOP is all about hiding state, which is the opposite of referential transparency. Are you saying we should never map/fold over OOP ranges? That seems like an unnecessary restriction for dogma's sake. Obviously, map() has to be lazy to support infinite ranges. But I assume that reduce() must be eager so that you actually get a result (I mean, it could probably be made lazy at enormous expense, but that would just be silly). So, if you want side effects, I guess you have to do the slightly dirty trick of calling reduce() without actually reducing anything. I guess the right thing to do would be to make a new algorithm that implements an eager map() but perhaps doesn't bother with the result, called invoke(). This carries none of the semantic baggage of well-known pure higher-order functions, and even sounds more OOP-like. Most of the other features of map() (like parallel iteration) are pretty nice to have in eager form. Dave
Re: Ultra-pure map()?
On Saturday, 28 December 2013 at 09:18:00 UTC, David Held wrote: On 12/27/2013 7:32 PM, Marco Leise wrote: [...] Side effects and altering the input object itself makes me want to pull out my crucifix. You shall not have impurity in your functional style code! Why not? There are many impure functional languages, and most non-functional languages that allow functional style allow mutation. OOP is all about hiding state, which is the opposite of referential transparency. Are you saying we should never map/fold over OOP ranges? That seems like an unnecessary restriction for dogma's sake. Obviously, map() has to be lazy to support infinite ranges. But I assume that reduce() must be eager so that you actually get a result (I mean, it could probably be made lazy at enormous expense, but that would just be silly). So, if you want side effects, I guess you have to do the slightly dirty trick of calling reduce() without actually reducing anything. I guess the right thing to do would be to make a new algorithm that implements an eager map() but perhaps doesn't bother with the result, called invoke(). This carries none of the semantic baggage of well-known pure higher-order functions, and even sounds more OOP-like. Most of the other features of map() (like parallel iteration) are pretty nice to have in eager form. Dave If you want to get result just now, then use 'array' function from std.array module. map!fun(range).array; or array(map!fun(range));
Re: Ultra-pure map()?
David Held: Why not? Because mixing map/filter and wild unrestrained side effects is asking for troubles (bugs in your code). Bye, bearophile
Re: Range of n lines from stdin
Many thanks to Marco, Ali and Jakob for the answers! On Saturday, 28 December 2013 at 08:56:53 UTC, Jakob Ovrum wrote: On Friday, 27 December 2013 at 20:30:52 UTC, Ivan Kazmenko wrote: Hmm?.. From my experience, attempting to use a range in a wrong way usually results in a compilation error. For example, I can't do n.iota.map!(_ = readln).sort()) since MapResult isn't a random access range with swappable elements. I can instead do n.iota.map!(_ = readln).array().sort()) and it allocates an array and works as expected. So, how do I misuse that range? Yes, the idea is that ranges only present interfaces that make sense, so cases of misuse will result in a compilation error. However, hacks like using map with functions that ignore their argument(s) throws that out of the window: `r` in `auto r = n.iota.map!(_ = readln);` claims to support forward, bidirectional and random access (all read-only, as the argument function returns by value) as well as slicing, but none of these make any sense; all access primitives do exactly the same thing, with the result being different every time. Even the simplest invariants fail, such as `r.front == r.front`, and `popFront`, `popBack` and slicing only has a binary effect, whether or not the range is empty yet. OK, I'm now beginning to understand how hacky is that. All the random number generator types in `std.random` are infinite forward ranges of random numbers, which is completely fine. For any PRNG `r`, `r.front == r.front` is true, and remains the same number until `r.popFront()`, it correctly has no length and is always non-empty (infinite range), and `r.save` works correctly etc. So, for both of my examples, support for desired behavior is provided at the different side: not a non-caching repeat for a given function but a range of lines or random numbers with the desired properties instead of such function. Maybe that's usually the right thing to do in the general case, too... Perhaps there's a wholly different way of thinking about this in which the first definition makes much more sense than then second one from the start. If so, please share it. All you have to do is look at the signature of the function, which is the primary part of its documentation: Repeat!T repeat(T)(T value); It takes one value of any type T, not a function pointer or delegate that returns T. Even if you give it a function pointer or delegate (which your example does not), it will simply repeat that function pointer or delegate, never calling it. So what I initially wanted is possible with something like (I just checked): (readln!(string)) . repeat(n) . map!(f = f('\n')) However, I'm having a hard time trying to get rid of !(string) and '\n' to make something like the following work: (readln) . repeat(n) . map!(f = f()) Anyway, even the second line (which does not compile) looks cryptic a bit. And it still has the problem of silently adding empty lines after end-of-file was reached. [1] ... in D we have something (slightly controversial) called the `lazy` parameter storage class, but when used, it is clearly visible in the signature of the function. http://dlang.org/function.html#parameters Thank you for the link. This is indeed what was my other expectation for repeat. Ivan Kazmenko.
Re: Ultra-pure map()?
On 12/28/2013 10:17 AM, David Held wrote: On 12/27/2013 7:32 PM, Marco Leise wrote: [...] Side effects and altering the input object itself makes me want to pull out my crucifix. You shall not have impurity in your functional style code! Why not? There are many impure functional languages, and most non-functional languages that allow functional style allow mutation. OOP is all about hiding state, which is the opposite of referential transparency. That's news to me. OOP does not mandate a procedural programming style. ... Obviously, map() has to be lazy to support infinite ranges. ... So, if you want side effects, I guess you have to do the slightly dirty trick of calling reduce() without actually reducing anything. ... What's the point? There are cleaner ways of doing the same. The implementation of map assumes that the result is independent of how it is iterated, and using it with callables that make it fail this criterion is usually at best confusing and at worst a bug. I guess the right thing to do would be to make a new algorithm that implements an eager map() but perhaps doesn't bother with the result, called invoke(). ... I wouldn't call this an 'eager map'. It's a shallow wrapper around a foreach loop.
Re: getting __DIR__ and __TIME__ of compilation?
On 2013-12-27 21:14, Ravn wrote: Eh, it does? :-? It prints a relative path when I used writeln(__FILE__), I'm on windows 7. Hmm, ok. It prints the full path when I run it via my text editor. But it prints the relative path when I run it via the command line. Tried enum path = dirName(__FILE__), compiles normally, no error from the compiler, but it still returns a relative path instead of a fullpath in my machine. Yes, same here, don't know why it didn't compile the first time I tried it. Perhaps this deserves an enhancement request. I really though __FILE__ would give the full path. -- /Jacob Carlborg
importing modules from a function
Hi, A moment ago I was reading a reply to one of my posts, and noticed Artur Skawina did this: void main(string argv[]) { import std.string; ... I didn't know D allowed importing modules from a function. Now, my question is: what is the advantage of this over importing the regular way? Regards, Hugo
Custom binary operators
Is there any way with D to define custom binary operators for user-defined types? I'm thinking of examples like MATLAB/Octave using the operators .+, .-, etc. to define element-wise addition, subtraction, etc. of matrices. AFAICS just doing something like auto opBinary(string op, T)(T rhs) if (op == .+) { ... } ... won't work, because the parser won't accept a code line like auto c = a .+ b; ... but is there some way to make this work? Assuming that it's not possible to define custom operators in regular code, I guess the alternative is to use templates to ensure an override of the regular + operator?
Re: Custom binary operators
AFAIK it is intentionally banned to constrain operator overloading abuse.
Re: importing modules from a function
On Saturday, 28 December 2013 at 14:23:17 UTC, Hugo Florentino wrote: I didn't know D allowed importing modules from a function. Now, my question is: what is the advantage of this over importing the regular way? Regards, Hugo Several advantages: 1) It is easier to maintain the code as origins of imported symbols become obvious immediately - less chance to get unused imports hanging around after some refactoring. 2) Considerably smaller chance of name clash between symbols from different modules (can only clash if used within same function / scope) 3) If it is templated function / scope, it won't be imported unless template is instantiated. lazy import effect. That may improve compilation times quite a lot in certain style of code.
Automatic translation of opUnary!++ into opOpAssign!+
So, while I was studying the apropriate template constraints for my shiny new iota implementation, I found out this funny thing: import std.stdio; class Test{ int x = 41; Test opOpAssign(string op)(int rhs) if (op == +) { x += rhs; return this; } } void main() { Test t1 = new Test; //class Test has no opUnary defined, so the following //gets automagically converted into (t1) += (1) ++t1; writeln(t1.x); //prints 42, correct! } This actually comes really handy, but I couldn't find it into the language documentation on dlang.org, so it surprised me. Did I miss it in the language specification? Should we add it somewhere to the docs? Anyone with some spare time care to explain briefly what was the rationale behind this?
Re: Custom binary operators
On 28/12/13 16:24, Dicebot wrote: AFAIK it is intentionally banned to constrain operator overloading abuse. Ahh, makes sense. But isn't it possible to do something with templates that would allow for something like, auto a = matrix(...); auto b = matrix(...); auto c = ElementWise!(a * b); ... where the ElementWise template would ensure that the binary operation is applied successively to corresponding pairs of elements from the matrices?
Re: Custom binary operators
On Saturday, 28 December 2013 at 16:33:24 UTC, Joseph Rushton Wakeling wrote: On 28/12/13 16:24, Dicebot wrote: AFAIK it is intentionally banned to constrain operator overloading abuse. Ahh, makes sense. But isn't it possible to do something with templates that would allow for something like, auto a = matrix(...); auto b = matrix(...); auto c = ElementWise!(a * b); ... where the ElementWise template would ensure that the binary operation is applied successively to corresponding pairs of elements from the matrices? how about: a.elementWise * b where a.elementWise returns a wrapper struct around a that implements elementwise arithmetic as opposed to the normal arithmetic. The operators would return instances of Matrix, not elementWise, to avoid accidentally spilling a Matrix.ElementWise struct in to ensuing code unintentionally. With a shorter alias it's rather neat. auto e = ((a .EW* b) .EW/ c ) * d;
Re: Custom binary operators
On 28/12/13 18:50, John Colvin wrote: how about: a.elementWise * b where a.elementWise returns a wrapper struct around a that implements elementwise arithmetic as opposed to the normal arithmetic. The operators would return instances of Matrix, not elementWise, to avoid accidentally spilling a Matrix.ElementWise struct in to ensuing code unintentionally. With a shorter alias it's rather neat. auto e = ((a .EW* b) .EW/ c ) * d; That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work à la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-(
Re: Automatic translation of opUnary!++ into opOpAssign!+
On Saturday, 28 December 2013 at 15:37:06 UTC, Francesco Cattoglio wrote: So, while I was studying the apropriate template constraints for my shiny new iota implementation, I found out this funny thing: import std.stdio; class Test{ int x = 41; Test opOpAssign(string op)(int rhs) if (op == +) { x += rhs; return this; } } void main() { Test t1 = new Test; //class Test has no opUnary defined, so the following //gets automagically converted into (t1) += (1) ++t1; writeln(t1.x); //prints 42, correct! } This actually comes really handy, but I couldn't find it into the language documentation on dlang.org, so it surprised me. Did I miss it in the language specification? Should we add it somewhere to the docs? Anyone with some spare time care to explain briefly what was the rationale behind this? I seem to remember that this is mentioned in TDPL? That's not spec of course, but I think it's mentioned here. I'm a bit fuzy about the shortcuts, but I *think* there are a couple other shortcuts like this, such as a += b = a = a + b? In any case, http://dlang.org/operatoroverloading.html; needs to be updated
DLL's reflection and Exceptions
Hello everyone! I'm currently working on a run-time reflection module. The intent of this module is to simplify the process of loading functions / classes / structs from DLL's loaded at run-time. It works something like this ATM: //In pluggin.d (A dll module) void foo() { ... } class Bar { ... } struct Baz { ... } ... more members At the end of the file i have a function like this export extern(C) MetaAssembly getMetaAssembly() { //Tuple of filters to only load relevant stuff. alias filters = standardFilters; return AssemblyGenerator!(filters, module1, ..., moduleN).data; } //In program.d (A host program) void main() { auto dll = loadDll(pluggin0.dll); MetaAssembly assembly = dll.func!(getter_t)(getMetaAssembly)() //Use assembly to find some classes //construct them and invoke some methods. MetaClass c = assembly. classes. find!(x = x.name == Foo)[0]; RTObject fooObj = c.constructors[0].create(); MetaMethod method = c.methods[0]; method.invoke(fooObj, Hello); } AssemblyGenerator!(...) extracts all needed information from the modules and stores them in a collection of structs that can be used at run-time to do stuff like create instances / set fields / check attributes. Normal reflection stuff. This works fine for normal code flow. However it all falls apart as soon as any function located in a DLL throws an exception. If an exception is thrown the application freezes, usually visual studio crashes with First hand exception: Privileged Instruction (some address). I have hacked my way around this limitation like so: //pluggin.d alias exception_handler_t = void function(Throwable) nothrow; __gshared exception_handler_t exceptionHandler; //program.d Throwable t = null; void exceptionHandler(Throwable thrown) nothrow { t = thrown; } bool exceptionThrown() { return t !is null; } void rethrowException() { DLLException e = new DLLException(t.toString()); t = null; throw e; } void main() { auto dll = loadDLL(pluggin0.dll); MetaAssembly assembly = dll.func!(getter_t)(getMetaAssembly)() auto field = assembly. staticFields. find!(x = x.name == exceptionHandler); field.set(exceptionHandler) } The reflection api wrapps all functions / methods with a try - catch that will call the exceptionHandler if an exception occurs. At the calle side (program.a) after every call it will check if an exception was thrown and if so rethrowng it as a DLLException. This workaround works, (atleast for now) but i don't like it. It complicates the low-level reflection api alot and it only solves the problem of calls from program.d to pluggin.d not the other way around (unless i wrap them aswell). So now to the questions. 1. Why can't i throw exceptions over a DLL boundary? 2. Are there any problems with my hack other then the ones already stated? 3. Does other workarounds exist? Thank you for your time!
Re: Custom binary operators
On Sat, Dec 28, 2013 at 07:35:00PM +0100, Joseph Rushton Wakeling wrote: On 28/12/13 18:50, John Colvin wrote: how about: a.elementWise * b where a.elementWise returns a wrapper struct around a that implements elementwise arithmetic as opposed to the normal arithmetic. The operators would return instances of Matrix, not elementWise, to avoid accidentally spilling a Matrix.ElementWise struct in to ensuing code unintentionally. With a shorter alias it's rather neat. auto e = ((a .EW* b) .EW/ c ) * d; That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work à la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-( The other way is to use a compile-time DSL, which lets you implement whatever operators you want in whatever syntax you fancy. T -- Today's society is one of specialization: as you grow, you learn more and more about less and less. Eventually, you know everything about nothing.
scope(faliure) flow control.
int foo() { scope(failure) return 22; throw new Exception(E); } unittest { assert(foo() == 22); } Is this defined behavior? At least in x64 dmd the exception is swallowed and the assert evaluates to true. In any case what should happen? Should the method return or should the exception be propagated up the callstack?
Re: scope(faliure) flow control.
On Saturday, 28 December 2013 at 20:31:14 UTC, TheFlyingFiddle wrote: int foo() { scope(failure) return 22; throw new Exception(E); } unittest { assert(foo() == 22); } Is this defined behavior? At least in x64 dmd the exception is swallowed and the assert evaluates to true. In any case what should happen? Should the method return or should the exception be propagated up the callstack? It's rewritten as follows: int foo() { try { throw new Exception(E); } catch (Exception e) { // or whatever the D syntax is, I never used it return 22; } } So yes, it's intended. scope(exit) uses finally instead of catch.
Re: Custom binary operators
On Saturday, 28 December 2013 at 20:06:46 UTC, H. S. Teoh wrote: On Sat, Dec 28, 2013 at 07:35:00PM +0100, Joseph Rushton Wakeling wrote: On 28/12/13 18:50, John Colvin wrote: how about: a.elementWise * b where a.elementWise returns a wrapper struct around a that implements elementwise arithmetic as opposed to the normal arithmetic. The operators would return instances of Matrix, not elementWise, to avoid accidentally spilling a Matrix.ElementWise struct in to ensuing code unintentionally. With a shorter alias it's rather neat. auto e = ((a .EW* b) .EW/ c ) * d; That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work à la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-( The other way is to use a compile-time DSL, which lets you implement whatever operators you want in whatever syntax you fancy. T Yeah. To risk being glib, if you want a domain specific language, use a domain specific language. Then again, including some convenient abstraction for some common tasks while remaining within the main language is nice.
Re: scope(faliure) flow control.
On 12/28/2013 12:50 PM, Casper Færgemand shortt...@hotmail.com wrote: On Saturday, 28 December 2013 at 20:31:14 UTC, TheFlyingFiddle wrote: int foo() { scope(failure) return 22; throw new Exception(E); } unittest { assert(foo() == 22); } Is this defined behavior? At least in x64 dmd the exception is swallowed and the assert evaluates to true. In any case what should happen? Should the method return or should the exception be propagated up the callstack? It's rewritten as follows: int foo() { try { throw new Exception(E); } catch (Exception e) { // or whatever the D syntax is, I never used it return 22; There must also be the re-throwing of the caught exception: throw e; What happens is, the return statement does not allow that to happen. } } So yes, it's intended. scope(exit) uses finally instead of catch. The spec brings restrictions to scope(exit) and scope(success) but does not say much about scope(failure): http://dlang.org/statement.html#ScopeGuardStatement Yeah, it appears that OP's code is legal. Ali
extern(C) function declarations and extra keywords.
I was thinking of adding some keywords like final, pure, and nothrow in to my library to improve various things where improvements could be made. As I was thinking about this, I wondered about my extern(C) function declarations and how keywords could improve those as well. Since the C functions can't access anything from D code save for what is passed through as parameters, can it be called pure? And if so, does the compiler know how to distinguish C and D in this instance and make it inherently pure? Does purity do anything in terms of speed/safety here? I noticed that in Deimos and Derelict that most(if not all) C function declarations are marked as nothrow. What are the speed/safety benefits of including this? And likewise as with the pure aspect, does the compiler know how to distinguish C and D and make it inherently nothrow? C's name mangling doesn't allow function overloading, but as far as I know you can overload extern(C) functions in D. Does adding final help with speed improvements in the D side of things if added to an extern(C) function declaration? Thanks much!
Re: extern(C) function declarations and extra keywords.
Since the C functions can't access anything from D code save for what is passed through as parameters, can it be called pure? Probably not since it might not be pure and eg. mutate global variables. Does purity do anything in terms of speed/safety here? A pure function is expected to give the same result given the same parameters. Similar calls to a pure function (same parameters) can be optimized out by the compiler. I noticed that in Deimos and Derelict that most(if not all) C function declarations are marked as nothrow. What are the speed/safety benefits of including this? No speed or safety benefit, but it allows to call these C functions in functions marked nothrow themselves. As a rule of thumb you can put nothrow systematically when binding C code. And likewise as with the pure aspect, does the compiler know how to distinguish C and D and make it inherently nothrow? No. C's name mangling doesn't allow function overloading, but as far as I know you can overload extern(C) functions in D. Does adding final help with speed improvements in the D side of things if added to an extern(C) function declaration? No.