Re: Why does this template constraint not work?
If you want to accept any floating point type but not implicit conversions, then use std.traits.isFloatingPoint. Thank you that's good to know. Though for this particular example I was just making a basic demo of the problem.
Re: Ultra-pure map()?
Am Sat, 28 Dec 2013 01:54:26 + schrieb "John Colvin" : > On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote: > > import std.algorithm; > > import std.stdio; > > import std.conv; > > > > class Trivial > > { > > int sideEffect() { return n++; } > > override string toString() pure { return to!string(n); } > > int n; > > } > > > > void main() > > { > > Trivial[] objs = [ new Trivial ]; > > map!(o => o.sideEffect())(objs); > > writeln(objs); // [0] > > foreach (o; objs) o.sideEffect(); > > writeln(objs); // [1] > > } > > > > Can someone explain to me why map() is not equivalent to > > foreach in the code above? From what I can tell, map() doesn't > > do anything at all on objs, even though it is a perfectly > > legitimate range (as far as I can tell). > > > > Dave > > Map is lazy and is never iterated over in your code, therefore no > side effects. Yeah, this is kind of unintended usage. Typically with map you take some input range, apply some algorithm to each element, and return a range of the results. 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! -- Marco
Re: Why does this template constraint not work?
On Saturday, December 28, 2013 02:31:56 Ross Hays wrote: > Okay figured it out actually. If you are not going to allow > implicit conversion the appropriate constraint is... > > if (is (T == float)) If you want to accept any floating point type but not implicit conversions, then use std.traits.isFloatingPoint. > I said it last time I asked about is and I will say it again. It > is such a weird syntax... Heh. It works. And if you do a lot with template constraints, you'll get used to it. The main thing that avoids needing is expressions quite as much is std.traits, which can simplify many types of template constraints. - Jonathan M Davis
Re: Range of n lines from stdin
Am Fri, 27 Dec 2013 20:34:02 + schrieb "Ivan Kazmenko" : > Maybe the imperative should be "repeat is a function, and > arguments of functions should be evaluated only once"? It does > make sense from a language point of view, but somewhat breaks the > abstraction for me. The documentation is clear about it: "Repeats one value forever." It has nothing to do with purity, whether the input range is lazy or the element is fetched eagerly. If it was meant to do what you expected it would read: "Constructs a range from lazily evaluating the expression passed to it over and over." This is not a limitation of the language either I think, since arguments to functions can be declared "lazy". -- Marco
Re: getting __DIR__ and __TIME__ of compilation?
Am Fri, 27 Dec 2013 20:14:00 + schrieb "Ravn" : > 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. Too bad :-/ I hoped it would use absolute paths. -- Marco
Re: Why does this template constraint not work?
On Saturday, 28 December 2013 at 02:27:00 UTC, Ross Hays wrote: import std.stdio; void test(T)() if (is (T : float)) { writeln(typeid(T)); } void main() { test!int; } When I run this I am getting the output "int" My understanding of template constraints is that the call to test!int will not find a match since the function test only accepts float as a template parameter. I just ran into this problem while trying to understand something unrelated. Okay figured it out actually. If you are not going to allow implicit conversion the appropriate constraint is... if (is (T == float)) I said it last time I asked about is and I will say it again. It is such a weird syntax...
Why does this template constraint not work?
import std.stdio; void test(T)() if (is (T : float)) { writeln(typeid(T)); } void main() { test!int; } When I run this I am getting the output "int" My understanding of template constraints is that the call to test!int will not find a match since the function test only accepts float as a template parameter. I just ran into this problem while trying to understand something unrelated.
Re: Ultra-pure map()?
On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote: import std.algorithm; import std.stdio; import std.conv; class Trivial { int sideEffect() { return n++; } override string toString() pure { return to!string(n); } int n; } void main() { Trivial[] objs = [ new Trivial ]; map!(o => o.sideEffect())(objs); writeln(objs); // [0] foreach (o; objs) o.sideEffect(); writeln(objs); // [1] } Can someone explain to me why map() is not equivalent to foreach in the code above? From what I can tell, map() doesn't do anything at all on objs, even though it is a perfectly legitimate range (as far as I can tell). Dave Map is lazy and is never iterated over in your code, therefore no side effects.
Re: Ultra-pure map()?
On 12/27/2013 5:46 PM, David Nadlinger wrote: On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote: Can someone explain to me why map() is not equivalent to foreach in the code above? From what I can tell, map() doesn't do anything at all on objs, even though it is a perfectly legitimate range (as far as I can tell). map() constructs a range that invokes a given function on the source range if an element is requested – but only then. In other words, map is fully lazy. Functional programming was surely invented by labor unions! Dave
Re: Ultra-pure map()?
On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote: Can someone explain to me why map() is not equivalent to foreach in the code above? From what I can tell, map() doesn't do anything at all on objs, even though it is a perfectly legitimate range (as far as I can tell). map() constructs a range that invokes a given function on the source range if an element is requested – but only then. In other words, map is fully lazy. David
Ultra-pure map()?
import std.algorithm; import std.stdio; import std.conv; class Trivial { int sideEffect() { return n++; } override string toString() pure { return to!string(n); } int n; } void main() { Trivial[] objs = [ new Trivial ]; map!(o => o.sideEffect())(objs); writeln(objs); // [0] foreach (o; objs) o.sideEffect(); writeln(objs); // [1] } Can someone explain to me why map() is not equivalent to foreach in the code above? From what I can tell, map() doesn't do anything at all on objs, even though it is a perfectly legitimate range (as far as I can tell). Dave
Re: Compile time getTimes
On Saturday, December 28, 2013 01:08:37 Casper Færgemand" @puremagic.com wrote: > I'm writing a compiler that uses Pegged for parsing D code. > Pegged is fed a string with a special grammar syntax and changes > it into templated D code, which is in turn mixed in. Even with > just a small subset of D, Pegged currently produces 4000 lines of > dense code, and it consumes enough time for it to be bothersome > on every change, especially changes to the compiler that don't > touch the grammar. > > I wrote some simple code that uses datetime's getTimes to compare > modification time. If grammar.d was modified more recently than > precompiled_grammar.d, grammar.d will be churned through the > machine once more and the result overwrite the > precompiled_grammar.d. > > However, it works only on runtime. I moved stuff around and used > an enum for the mixin, forcing compile time function execution, > but it whines about getTimes being unusable: "Error: > GetFileAttributesExW cannot be interpreted at compile time, > because it has no available source code" > > Is there some hack available? Currently I run the compiler twice > to use the past precompiled stuff or run it once and accept that > it's slow. And this is D, so I really feel I shouldn't have to. =3 CTFE requires that all of the source code be available (which is not the case with C functions) and isn't able to interact with the file system or any kind of I/O (beyond importing a file as a string). So, I believe that it's impossible to do something like check file times at compile time. You'll have to restrict yourself to stuff that you can do in code without any kind of I/O. http://dlang.org/function.html#interpretation - Jonathan M Davis
Compile time getTimes
I'm writing a compiler that uses Pegged for parsing D code. Pegged is fed a string with a special grammar syntax and changes it into templated D code, which is in turn mixed in. Even with just a small subset of D, Pegged currently produces 4000 lines of dense code, and it consumes enough time for it to be bothersome on every change, especially changes to the compiler that don't touch the grammar. I wrote some simple code that uses datetime's getTimes to compare modification time. If grammar.d was modified more recently than precompiled_grammar.d, grammar.d will be churned through the machine once more and the result overwrite the precompiled_grammar.d. However, it works only on runtime. I moved stuff around and used an enum for the mixin, forcing compile time function execution, but it whines about getTimes being unusable: "Error: GetFileAttributesExW cannot be interpreted at compile time, because it has no available source code" Is there some hack available? Currently I run the compiler twice to use the past precompiled stuff or run it once and accept that it's slow. And this is D, so I really feel I shouldn't have to. =3
Re: Range of n lines from stdin
On Friday, 27 December 2013 at 20:30:52 UTC, Ivan Kazmenko wrote: On Friday, 27 December 2013 at 18:32:29 UTC, Jakob Ovrum wrote: If repeat could know whether its first argument is pure, it could then enable or disable front caching depending on purity... no way currently? `readln.repeat(n)` can also be written `repeat(readln(), n)`. Maybe that makes it more obvious what it does - reads one line from standard input and passes that to `repeat`, which returns a range that returns that same line `n` times. The confusion for me is this: does "repeat" mean "eagerly get a value once and then lazily repeat it n times" or "do what the first argument suggests (emit constant, call function, etc.) n times"? I guess it depends on the defaults of the language. Currently, I had no strong preference for one definition over the other when I saw the name. Maybe I would indeed prefer the first definition if I knew D better, I don't know. In the first definition, the "eagerly vs. lazily" contradiction in my mind is what scares me off from making it the default: if "repeat" is a lazy range by itself, why would it treat its argument eagerly? What if the argument is a lazy range itself, having a new value each time repeat asks for it? The first definition makes much more sense for me when I treat it this way: "repeat expects its first argument to be pure (not able to change between calls)". 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. Maybe the imperative should be "repeat is a function, and arguments of functions should be evaluated only once"? It does make sense from a language point of view, but somewhat breaks the abstraction for me.
Re: Range of n lines from stdin
On Friday, 27 December 2013 at 18:32:29 UTC, Jakob Ovrum wrote: (1) I can do n.iota.map!(_ => readln) to get the next n lines from stdin. This has several issues: * The result claims to have all kinds of range capabilities that don't make sense at all. Attempting to actually use these capabilities, likely indirectly through range algorithms, can cause all kinds of havoc. 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? * It will allocate a new buffer for the read line every time `front` is called, which is less granular than `byLine`'s allocation behaviour. * If `stdin` (or whatever file) only has `i` number of lines left in it where `i < n`, the range will erroneously report `n - i` number of empty lines at the end. * It's not showing intent as clear as it should be. Thank you for pointing these out! So it's not performant, not correct and not idiomatic. I understood only a part of that, but already asked for a better alternative. Well, that's more arguments to the same point. And yeah, stdin.byLine serves rather well in this particular case. So, what I ask for is some non-caching repeat for functions with side effects. More idiomatic than (1). Is there something like that in Phobos? It's hard generalize. For one, what is the empty condition? 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)) Is it an OK style to have an impure function in an UFCS chain? I assume by UFCS chain you mean range compositions in particular. It's not really about purity; impure links in the chain are fine (e.g. `byLine`). The issue is when the side effects are the only result - I think that is very bad style, and should either be rewritten in terms of return values, or rewritten to use an imperative style. 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. If repeat could know whether its first argument is pure, it could then enable or disable front caching depending on purity... no way currently? `readln.repeat(n)` can also be written `repeat(readln(), n)`. Maybe that makes it more obvious what it does - reads one line from standard input and passes that to `repeat`, which returns a range that returns that same line `n` times. The confusion for me is this: does "repeat" mean "eagerly get a value once and then lazily repeat it n times" or "do what the first argument suggests (emit constant, call function, etc.) n times"? I guess it depends on the defaults of the language. Currently, I had no strong preference for one definition over the other when I saw the name. Maybe I would indeed prefer the first definition if I knew D better, I don't know. In the first definition, the "eagerly vs. lazily" contradiction in my mind is what scares me off from making it the default: if "repeat" is a lazy range by itself, why would it treat its argument eagerly? What if the argument is a lazy range itself, having a new value each time repeat asks for it? The first definition makes much more sense for me when I treat it this way: "repeat expects its first argument to be pure (not able to change between calls)". 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. Ivan Kazmenko.
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 19:35:23 UTC, Jacob Carlborg wrote: On 2013-12-27 19:14, Ravn wrote: __FILE__ will return the full path (absolute path) of the file currently compiling. But that is not the same thing as getting the path to where the compilation was made. Eh, it does? :-? It prints a relative path when I used writeln(__FILE__), I'm on windows 7. On Friday, 27 December 2013 at 19:35:23 UTC, Jacob Carlborg wrote: On 2013-12-27 19:14, Ravn wrote: I would guess you could use __FILE__ with dirName, but that currently does not compile. 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.
Re: windows 8.1 and dirEntries
Thanks Ali. Stupid of me, it is the dirEntries call that opens the directory and tries to read contents. I did this (below), but it still leaves the odd situation that Documents and Settings cannot be opened, and surely non-administrators have access to this folder. try{ auto dirs = dirEntries(directory, SpanMode.shallow, false); foreach(DirEntry ent; dirs){ if(ent.isDir) d ~= ent.name; if(ent.isFile){ if(endsWith(ent.name, sufix)) f ~= ent.name; } } }catch(FileException ex){ writeln("Error reading directory, probably no administrator privilege"); } finally{}
Re: getting __DIR__ and __TIME__ of compilation?
On 2013-12-27 19:14, Ravn wrote: I need the absolute path __FILE__ during compile time, so far the only way I know to get absolute paths is by using std.path.absolutePath (which uses getcwd() as its base) and getcwd() itself (which doesn't seem to work during compile time). Is there any alternative on how to get the absolute path for a file during compile time besides using these functions? __FILE__ will return the full path (absolute path) of the file currently compiling. But that is not the same thing as getting the path to where the compilation was made. I would guess you could use __FILE__ with dirName, but that currently does not compile. -- /Jacob Carlborg
Re: Range of n lines from stdin
On Friday, 27 December 2013 at 14:27:01 UTC, Ivan Kazmenko wrote: Quick question. (1) I can do n.iota.map!(_ => readln) to get the next n lines from stdin. This has several issues: * The result claims to have all kinds of range capabilities that don't make sense at all. Attempting to actually use these capabilities, likely indirectly through range algorithms, can cause all kinds of havoc. * It will allocate a new buffer for the read line every time `front` is called, which is less granular than `byLine`'s allocation behaviour. * If `stdin` (or whatever file) only has `i` number of lines left in it where `i < n`, the range will erroneously report `n - i` number of empty lines at the end. * It's not showing intent as clear as it should be. (3) In the particular case of readln, we can substitute it with stdin.byLine.take(n) but the question remains for other impure functions. `byLine` with `take` has very different characteristics from `map` + `readln`, as explained above. So, what I ask for is some non-caching repeat for functions with side effects. More idiomatic than (1). Is there something like that in Phobos? It's hard generalize. For one, what is the empty condition? Is it an OK style to have an impure function in an UFCS chain? I assume by UFCS chain you mean range compositions in particular. It's not really about purity; impure links in the chain are fine (e.g. `byLine`). The issue is when the side effects are the only result - I think that is very bad style, and should either be rewritten in terms of return values, or rewritten to use an imperative style. Some people think otherwise, and it results in a lot of Phobos requests for a function that just eagerly evaluates a range and nothing more (sometimes called `eat`). I have yet to convince these people that they are wrong :) If repeat could know whether its first argument is pure, it could then enable or disable front caching depending on purity... no way currently? `readln.repeat(n)` can also be written `repeat(readln(), n)`. Maybe that makes it more obvious what it does - reads one line from standard input and passes that to `repeat`, which returns a range that returns that same line `n` times.
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 15:15:31 UTC, Jacob Carlborg wrote: You can use this ugly hack: Create a shell script with the following content. #!/bin/bash echo `pwd` > dir.txt dmd main.d -J. And the D source code: module main; enum compilePath = import("dir.txt"); pragma(msg, compilePath); Run the shell script to compile the D code. I end up using something similar to your 'hack', made a tiny wrapper in D that accepts the parameters that is supposed to go to dmd, get the absolute path of the compiled sourcecode using std.path.absolutePath(), save it inside a new .d file, the wrapper then calls the dmd compiler with .d added to the list of compiled files. Bit of a stretch, but it'll do for now. -Ravn-
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 15:23:37 UTC, Marco Leise wrote: No, but if you just want the path where your sources are you could use __FILE__ for any module and cut off the part of it that belongs to the module path. A lot of Phobos works at compile time, so you might be able to write a one-liner for that. I need the absolute path __FILE__ during compile time, so far the only way I know to get absolute paths is by using std.path.absolutePath (which uses getcwd() as its base) and getcwd() itself (which doesn't seem to work during compile time). Is there any alternative on how to get the absolute path for a file during compile time besides using these functions?
Re: Range of n lines from stdin
On 12/27/2013 06:26 AM, Ivan Kazmenko wrote: > n.iota.map!(_ => readln) > to get the next n lines from stdin. > So, what I ask for is some non-caching repeat for functions with side > effects. More idiomatic than (1). This request comes up once in a while. > Is there something like that in Phobos? As far as I know, no. Although, bearophile may have a bug report to track the issue. :) > Is it an OK style to have an impure function in an UFCS chain? I don't think any different than side effects in other parts of the language. In other words, side effects are a part of D. :) Ali
Re: imports and a data structure (any critique welcome)
On Friday, 27 December 2013 at 16:08:09 UTC, Jonathan wrote: Let me just check my understanding: If a function says it returns a thing of type T, it really does return something whose outermost shape is T; however, if it contains pointers to other things, and these were stack allocated, the pointers might be readdressed. The pointers remain exactly how they were, but stack allocated memory is released when the function that allocated it returns (that's just how the stack works, it's temporary scratch space for functions) so the pointers are left pointing to garbage.
Re: imports and a data structure (any critique welcome)
On 12/27/2013 05:08 PM, Jonathan wrote: Let me just check my understanding: If a function says it returns a thing of type T, it really does return something whose outermost shape is T; however, if it contains pointers to other things, and these were stack allocated, the pointers might be readdressed. ... Well, the it is returned as-is, but the value of something that contains indirections is in general only meaningful in the context of a corresponding heap, stack and static data segment. Here the stack is changed in a way that renders the pointers in the returned value meaningless, so type safety does not hold. (Outside of @safe code, type safety is conditional on the programmer making sure that code does not violate certain invariants.) @Bearophile: in your example, why is the array heap allocated? This is just how the language feature works. The array literal allocates an array on the heap and gives you a slice to it. (If you assign such a literal to a static variable during compilation, it will actually be stored in the static data segment.) For arrays do you not need to use new? ... You can also allocate a new array using new: auto x = new int[](4); // allocate array of 4 elements ... It makes sense that union is not type safe. If I have a struct like this ... } That seems like a bad practice leaving one of the fields uninstantiated. Is this is a sign that I should be using an object oriented approach, or is there a way to clean this up. ... The only way to clean it up is to hide it behind a type safe interface. (Besides concise syntax, that's all the ADT mixin template is doing essentially.) I have to admit, I don't understand the mixin/template stuff right now. However the mixin ADT thing seems pretty sexy, so it might be a good idea to learn enough to understand what is going on there. It parses the given specification (q{this is a string}), generates D code as a string using the built-in D interpreter that the compiler comes with. ("Using CTFE".) Then the generated D code is "mixed in" and compiled. The problem I have with this is if it ends up describing a struct in the background, will I have to keep a bunch of conventions straight in my head, or are there lots of utilities for working with this kind of thing (i.e. can I do a case operation, and recurse on subterms)? Well, it is implemented in D code, so that's up to you. The proof-of-concept implementation supports pattern matching. Are templates considered a good practice in D? ... Yes, but mixins less so. (They are considered good if there is no other way to get what you want.) Also, would mixin ADT!q{ Term: Var char | Op char Term[] | Ptr Term*}; be considered valid. If so, then it would allow me to create a term t get its pointer, p, and then have Op 'g' (Ptr p, Ptr p) so that in rewriting g(t,t), I only need to rewrite t once. ... A full-blown ADT implementation probably would not tolerate mutable aliasing. Suppose a seasoned D programmer were thinking about this problem: would (s)he opt for an object oriented approach or the use of structs. The main point of this data structure is to implement term rewriting. There will probably be a lot of object creation -- especially in building and applying substitution lists. I don't see any real benefit of one of the other for this application. I tend not to worry too much about being performance critical i.e. cutting corners to shave off constants at the expense of losing safety ... I tend to prefer a simpler approach as long as I can guarantee that the big-O is the same -- however, I try to avoid even logarithmic "blowups" in comparable approaches ... You should probably just go with classes then. (It's what I've done for a recent toy implementation of the calculus of constructions.)
Re: inotify and recursion
On 12/27/13 15:13, Artur Skawina wrote: >struct MyInotifyEvent(size_t BS) { > inotify_event event; > char[BS] buffer; > alias event this; >} >[...] >enum bufsiz = inotify_event.sizeof + PATH_MAX + 1; >auto event = cast(MyInotifyEvent!bufsiz*)malloc(bufsiz); >[...] >writeln("Name:", event.buffer[0..event.len-1]); // 2do: strip any extra > trailing \0s. Well, that could get awkward, as the inotify api doesn't really support disabling event batching. A saner design would be something like the code below. artur struct INotify { Fd fd; import std.exception; import core.sys.posix.unistd; this(cint flags) { fd = inotify_init(flags); errnoEnforce(fd!=-1); } ~this() { close(fd); } Wd add(const char* name, uint mask) { return inotify_add_watch(fd, name, mask); } Fd remove(Wd wd){ return inotify_rm_watch(fd, wd); } bool get(CB)(CB cb) { void[4*1024] buffer = void; auto got = read(fd, &buffer, buffer.sizeof); if (got<=inotify_event.sizeof) return false; size_t off = 0; while (off<=got-inotify_event.sizeof) { auto evp = cast(inotify_event*)&buffer[off]; auto namebuf = evp.len ? (cast(char*)&evp.name)[0..evp.len-1] : null; while (namebuf.length && !namebuf[namebuf.length-1]) --namebuf.length; cb(evp, namebuf); off += inotify_event.sizeof + evp.len; } assert(off==got); return true; } } void main(string argv[]) { import std.string; auto ntf = INotify(0); foreach (arg; argv[1..$]) ntf.add(toStringz(arg), IN_MODIFY); void myCallback(/*scope*/ const inotify_event* ev, /*scope*/ char[] name) { /* Don't even think about escaping any of the args. Dup if necessary. */ import std.stdio; writeln(*ev, " \"", name, "\""); } while (1) ntf.get(&myCallback); } // libc i/f follows: alias uint32_t = uint; alias cint = int; alias Fd = cint; extern(C) { Fd inotify_init(); Fd inotify_init1(cint flags); Wd inotify_add_watch(Fd fd, const char* pathname, uint mask); Fd inotify_rm_watch(Fd fd, Wd wd); } Fd inotify_init(cint flags) { return inotify_init1(flags); } enum IN_MODIFY = 0x0002; /* DEFINEME */ struct Wd { Fd fd; alias fd this; } struct inotify_event { Wd wd; /* Watch descriptor */ uint32_t mask; /* Mask of events */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of name field */ char name[0]; /* Optional null-terminated name */ void toString(DG, FT)(scope DG sink, FT fmt) const @trusted { import std.format; foreach (I, E; this.tupleof) static if (I
Re: imports and a data structure (any critique welcome)
Timon Gehr: https://d.puremagic.com/issues/show_bug.cgi?id=11558 We are getting there :-) but implying that you are somehow ethically superior and that I am not human seems to go a little far. :o) Sorry. In my opinion that kid of code is not very readable, spaces help to eye to chunk the code better. They hurt there because they add noise and don't help. The parentheses in "(x < $) ? x : 0" are not necessary, but they help chunk the code, the first chunk is the condition. This is especially useful when that condition gets a little longer. Bye, bearophile
Re: imports and a data structure (any critique welcome)
Found your other post nwm.
Re: imports and a data structure (any critique welcome)
On Friday, 27 December 2013 at 00:23:58 UTC, Jonathan wrote: I come from Haskell, so please excuse any functional programming idiosyncracies I have :) In Haskell, I have a datatype for representing so called terms which looks like: data Term = Var Char | Op Char [Term] i.e. a Term is a variable (denoted by an Int) or an operation (whose name is also denoted by an int), applied to a list of its arguments. For example, f(g(x,y),a(),x) is represented by Op 'f' [Op 'g' [Var 'x',Var 'y'],Op 'a' [], Var 'x] Now, the reason I am writing in D is twofold. First, I want to learn the D language, and second I really need pointers to reduce certain complexities in the operations (Haskell does not have observable sharing). Could you please clarify the question? I did not understand what you wanted to ask.
Re: inotify and recursion
On Fri, 27 Dec 2013 12:56:25 +, Gary Willoughby wrote: On Friday, 27 December 2013 at 03:39:58 UTC, Hugo Florentino wrote: BTW, it it a requirement to use malloc, and if so, when would I need to free the memory allocated by it? I use a static ubyte array. I've been using inotify quite a bit and found it to be very good but there are a few things to keep in mind though. First it can block further program execution when watching files. To avoid this use the select function in 'core.sys.posix.sys.select'. Thanks. Have you ever tried using epoll? I have read that for asynchronous things it works much better than select.
Re: imports and a data structure (any critique welcome)
Let me just check my understanding: If a function says it returns a thing of type T, it really does return something whose outermost shape is T; however, if it contains pointers to other things, and these were stack allocated, the pointers might be readdressed. @Bearophile: in your example, why is the array heap allocated? For arrays do you not need to use new? From the documentation: "BUGS: Currently, Algebraic does not allow recursive data types." ... So maybe in the future, I can refactor to that. It makes sense that union is not type safe. If I have a struct like this struct F { enum Case {case1, case2} Case case; int x; string y; this(int x_in) { x = x_in; case = case1; } this(string y_in) { y = y_in; case = case2; } } That seems like a bad practice leaving one of the fields uninstantiated. Is this is a sign that I should be using an object oriented approach, or is there a way to clean this up. I have to admit, I don't understand the mixin/template stuff right now. However the mixin ADT thing seems pretty sexy, so it might be a good idea to learn enough to understand what is going on there. The problem I have with this is if it ends up describing a struct in the background, will I have to keep a bunch of conventions straight in my head, or are there lots of utilities for working with this kind of thing (i.e. can I do a case operation, and recurse on subterms)? Are templates considered a good practice in D? Also, would mixin ADT!q{ Term: Var char | Op char Term[] | Ptr Term*}; be considered valid. If so, then it would allow me to create a term t get its pointer, p, and then have Op 'g' (Ptr p, Ptr p) so that in rewriting g(t,t), I only need to rewrite t once. Suppose a seasoned D programmer were thinking about this problem: would (s)he opt for an object oriented approach or the use of structs. The main point of this data structure is to implement term rewriting. There will probably be a lot of object creation -- especially in building and applying substitution lists. I don't see any real benefit of one of the other for this application. I tend not to worry too much about being performance critical i.e. cutting corners to shave off constants at the expense of losing safety ... I tend to prefer a simpler approach as long as I can guarantee that the big-O is the same -- however, I try to avoid even logarithmic "blowups" in comparable approaches ...
Re: imports and a data structure (any critique welcome)
On 12/27/2013 02:45 PM, bearophile wrote: Timon Gehr: mixin ADT!q{ Term: Var char | Op char Term[] }; void main(){ const expr = Op('f', [Op('g',[Var('x'), Var('y')]), Op('a',[]), Var('x')]); } Where is ADT defined? https://d.puremagic.com/issues/show_bug.cgi?id=10431 (And why isn't it a Phobos patch on GitHub?) ... https://d.puremagic.com/issues/show_bug.cgi?id=11558 That's too much compact :-) Humans put a space around operators, Feel free to reformat, but implying that you are somehow ethically superior and that I am not human seems to go a little far. :o) and sometimes some parentheses don't hurt: They hurt there because they add noise and don't help.
Re: imports and a data structure (any critique welcome)
Am Fri, 27 Dec 2013 13:45:10 + schrieb "bearophile" : > Timon Gehr: > > > mixin ADT!q{ Term: Var char | Op char Term[] }; > > > > void main(){ > > const expr = Op('f', [Op('g',[Var('x'), Var('y')]), > > Op('a',[]), Var('x')]); > > } > > Where is ADT defined? (And why isn't it a Phobos patch on GitHub?) > > > > convertNum could be written more compactly as: > > char convertNum(int x){ > > return "exyzfgh"[x<$?x:0]; > > That's too much compact :-) Humans put a space around operators, > and sometimes some parentheses don't hurt: > > char convertNum(in int x) pure nothrow > in { > assert(x >= 0); > } body { > return "exyzfgh"[(x < $) ? x : 0]; > } > > Bye, > bearophile Before you go _that_ far, just write: char convertNum(in size_t x) pure nothrow { return "exyzfgh"[(x < $) ? x : 0]; } :-) -- Marco
Re: getting __DIR__ and __TIME__ of compilation?
On 2013-12-27 16:23, Marco Leise wrote: No, but if you just want the path where your sources are you could use __FILE__ for any module and cut off the part of it that belongs to the module path. A lot of Phobos works at compile time, so you might be able to write a one-liner for that. That might not be the same as where the compilation is performed. -- /Jacob Carlborg
Re: getting __DIR__ and __TIME__ of compilation?
Am Fri, 27 Dec 2013 12:43:15 + schrieb "Ravn" : > On Friday, 27 December 2013 at 11:56:08 UTC, Ali Çehreli wrote: > > However, __FILE__ happens to be the current source file that is > > being compiled but I think the OP wants the current compilation > > directory. Being a C library file, getcwd() does not work at > > compile time: > > > > import std.stdio; > > > > void main() > > { > > import std.path: dirName; > > > > enum compiledFile = __FILE__; > > writeln(compiledFile); > > > > static const compileTime = __DATE__ ~ " " ~ __TIME__; > > writeln(compileTime); > > > > /* > > import std.file: getcwd; > > static const compilationDir = getcwd(); > > writeln(compilationDir); > > > > Error: getcwd cannot be interpreted at compile time, > > because it has no available source code > > */ > > } > > > > Ali > > Yes, just like what Ali said above, > > __FILE__, __DATE__ and __TIME__ do work for their respective > usages, > but I'm also looking for a way to get the current compilation > directory during compile time, and getcwd() doesn't seem to be > working. > > Isn't there something like __DIR__ or __PATH__ that I can use to > get that information? > > -Ravn- No, but if you just want the path where your sources are you could use __FILE__ for any module and cut off the part of it that belongs to the module path. A lot of Phobos works at compile time, so you might be able to write a one-liner for that. -- Marco
Re: Range of n lines from stdin
Am Fri, 27 Dec 2013 14:26:59 + schrieb "Ivan Kazmenko" : > Quick question. > > (1) I can do > n.iota.map!(_ => readln) > to get the next n lines from stdin. > > (2) However, when I do > readln.repeat(n) > it looks clearer but works differently: preserves front and reads > only one line. > > (3) In the particular case of readln, we can substitute it with > stdin.byLine.take(n) > but the question remains for other impure functions. > > So, what I ask for is some non-caching repeat for functions with > side effects. More idiomatic than (1). Is there something like > that in Phobos? Is it an OK style to have an impure function in > an UFCS chain? > > If repeat could know whether its first argument is pure, it could > then enable or disable front caching depending on purity... no > way currently? repeat() is only meant to repeat the same first element over and over. I think it would be wrong if it changed its value during iteration. A wrapper struct could be more ideomatic: FuncRange!readln.take(n) > Ivan Kazmenko. -- Marco
Re: getting __DIR__ and __TIME__ of compilation?
Yes, just like what Ali said above, __FILE__, __DATE__ and __TIME__ do work for their respective usages, but I'm also looking for a way to get the current compilation directory during compile time, and getcwd() doesn't seem to be working. Isn't there something like __DIR__ or __PATH__ that I can use to get that information? You can use this ugly hack: Create a shell script with the following content. #!/bin/bash echo `pwd` > dir.txt dmd main.d -J. And the D source code: module main; enum compilePath = import("dir.txt"); pragma(msg, compilePath); Run the shell script to compile the D code. -- /Jacob Carlborg
Re: Which Libraries?
On 2013-12-27 08:00, Rikki Cattermole wrote: There is also DQuick and DWT. DWT [1] has OpenGL support as well. Here's a snippet that uses DWT and OpenGL: https://github.com/d-widget-toolkit/org.eclipse.swt.snippets/blob/master/src/org/eclipse/swt/snippets/Snippet195.d [1] https://github.com/d-widget-toolkit/dwt -- /Jacob Carlborg
Re: Function with C calling convention but D mangling
On 2013-12-23 12:20, Benjamin Thaut wrote: Yes it would, but then I would have to define some mangling for myself. You can do something like this: void foo (); extern (C) pragma(mangle, foo.mangleof) void foo () { } I'm pretty sure you remove the duplication with a mixin. -- /Jacob Carlborg
Range of n lines from stdin
Quick question. (1) I can do n.iota.map!(_ => readln) to get the next n lines from stdin. (2) However, when I do readln.repeat(n) it looks clearer but works differently: preserves front and reads only one line. (3) In the particular case of readln, we can substitute it with stdin.byLine.take(n) but the question remains for other impure functions. So, what I ask for is some non-caching repeat for functions with side effects. More idiomatic than (1). Is there something like that in Phobos? Is it an OK style to have an impure function in an UFCS chain? If repeat could know whether its first argument is pure, it could then enable or disable front caching depending on purity... no way currently? Ivan Kazmenko.
Re: inotify and recursion
On 12/27/13 14:28, David Eagen wrote: > I had trouble getting the file name from the event. I think it's because the > inotify module has name defined as char[0]. So I did this, which prints the > name by using the extra data beyond the inotify_event struct itself: > > > void* buf = GC.malloc(bufsiz); > > /* wait for an event to occur */ > size_t readlen = read(inotfd, buf, bufsiz); > inotify_event* event = cast(inotify_event*) (buf); > > /* process event struct here */ > writeln("Received inotify event:"); > writeln("Bytes read: ", readlen); > writeln("Length: ", event.len); > writeln("Name:", cast(char[])(buf[event.len..readlen])); writeln("Name:", (cast(char*)&event.name)[0..event.len-1]); // 2do: strip any extra trailing \0s. It's probably easier (and safer) if you do it like this: struct MyInotifyEvent(size_t BS) { inotify_event event; char[BS] buffer; alias event this; } [...] enum bufsiz = inotify_event.sizeof + PATH_MAX + 1; auto event = cast(MyInotifyEvent!bufsiz*)malloc(bufsiz); [...] writeln("Name:", event.buffer[0..event.len-1]); // 2do: strip any extra trailing \0s. artur
Re: imports and a data structure (any critique welcome)
Timon Gehr: mixin ADT!q{ Term: Var char | Op char Term[] }; void main(){ const expr = Op('f', [Op('g',[Var('x'), Var('y')]), Op('a',[]), Var('x')]); } Where is ADT defined? (And why isn't it a Phobos patch on GitHub?) convertNum could be written more compactly as: char convertNum(int x){ return "exyzfgh"[x<$?x:0]; That's too much compact :-) Humans put a space around operators, and sometimes some parentheses don't hurt: char convertNum(in int x) pure nothrow in { assert(x >= 0); } body { return "exyzfgh"[(x < $) ? x : 0]; } Bye, bearophile
Re: inotify and recursion
On Friday, 27 December 2013 at 10:56:55 UTC, Artur Skawina wrote: You probably meant read(inotfd, event, (*event).sizeof); but in this case the inotify_event structure contains an optional trailing buffer, so it should be read(inotfd, event, bufsiz); artur Yes, thanks for the correction. I had trouble getting the file name from the event. I think it's because the inotify module has name defined as char[0]. So I did this, which prints the name by using the extra data beyond the inotify_event struct itself: void* buf = GC.malloc(bufsiz); /* wait for an event to occur */ size_t readlen = read(inotfd, buf, bufsiz); inotify_event* event = cast(inotify_event*) (buf); /* process event struct here */ writeln("Received inotify event:"); writeln("Bytes read: ", readlen); writeln("Length: ", event.len); writeln("Name:", cast(char[])(buf[event.len..readlen]));
Re: imports and a data structure (any critique welcome)
On 12/27/2013 05:54 AM, Jonathan wrote: Thanks to everyone that has replied. @Timon Gehr: Thank you. In reply to [1]: that is an interesting issue that I don't really understand right now. Can you explain exactly where I invoke undefined behavior? It was my understanding that structs are passed and returned by value, and the assignment x = some struct makes a copy of some struct and stores it in x. Perhaps I don't understand the type system of D? The original code takes the address of variables that are allocated on the stack. Function-local variables (fortunately/unfortunately) have limited lifetime unless they are closed over. If their address is dereferenced after they have gone out of scope, you are accessing locations on the stack that may have been populated with new data of different type in the meantime. Eg. any usage of the '&' operator in the original code is wrong, because the addresses are part of the structure that the function returns. If a function returns T where T is some struct, does the function result in a struct? I am having trouble finding these subtleties in the documentation (but I also acknowledge that this is probably my fault and not the documentation's). ... The documentation can indeed be a little sparse. This may help you: http://ddili.org/ders/d.en/index.html (I have not read a lot of it, but it appears to put special focus on subtleties as it is targeted also at programming novices.) Does auto do a simple type inference to find out that Term* should be there? No, auto is just a place holder used to show that what follows is a declaration. What is important to invoke type deduction is that there is no type specified. (It indeed is very simple, all it does is copying the type of the initializer.) Is there an advantage to using auto? ... Less redundancy. Eg. I would have been able to remove the undefined behaviour faster if type deduction was already in use. I can't seem to put @safe: at the top of the file Yes, I missed the union. (It is not generally a memory safe construct.) -- is it the same as compiling with -safe. I think this compiler switch no longer exists. Is there a way to add this as a source annotation? ... Yes, @safe: at the top of the file is the source annotation. Is ! an operator in e.g. ADT!q ... ... It is notation for template instantiation. http://dlang.org/template.html http://ddili.org/ders/d.en/templates.html http://ddili.org/ders/d.en/templates_more.html What is the mixin bit doing? It imports the declarations within the template body into the current scope. Can you point me towards any tutorials, or should I buy the book? ... http://ddili.org/ders/d.en/mixin.html http://dlang.org/template-mixin.html I don't think the book discusses mixins in depth. @bearophile: Thank you for the welcome. That is odd; Maybe he just does not know a lot of Haskell programmers. :o) I find that D shares a philosophy closer to Haskell than many of the "lower level" languages like C. ... I guess some missing type system features can turn off Haskell programmers. Most importantly, the type system is monomorphic. (Templates cover some use cases of a polymorphic type system.) So let me just say, I really do need to build a structure that can have a shared reference to a substructure. I will be rewriting these terms, and the problem is that e.g. f(t) -> g(t,t) I don't want to copy t, but store a reference to t, so that if t can be re-written, it will only be rewritten once. However, this is really *not* an algebraic type since sharing is not algebraic, so I figured that this would not be a good solution. The object oriented approach would be really nice. Since objects are passed by reference, I should get sharing for free. The only reason I didn't use an object oriented approach off the bat is that I don't think I completely understand when to use a struct versus an object. Objects are often used for convenient virtual function tables, for reference semantics, and sometimes to emulate closed sum types in a memory safe fashion. structs are typically used for more manual control and for implementing types with (part-wise) value semantics. Using structs seem to fit the story better, because the structure isn't really emitting any functionality, I just want to perform some functions to it. Some might claim that the structure emits visitor functionality. :o) So using structs feel like a better fit. Feel free to correct me here. What are some of the drawbacks to using object. They may waste some memory. How much more time overhead is there once the object is created? ... Virtual function calls have some overhead compared to static function calls, but it is less bad on x86/x64 than on some other architectures. How performance-critical is your application? You are right, I probably look like an idiomless noob! I totally am! Hopefully an understanding of the appropriate key
Re: inotify and recursion
On Friday, 27 December 2013 at 03:39:58 UTC, Hugo Florentino wrote: BTW, it it a requirement to use malloc, and if so, when would I need to free the memory allocated by it? I use a static ubyte array. I've been using inotify quite a bit and found it to be very good but there are a few things to keep in mind though. First it can block further program execution when watching files. To avoid this use the select function in 'core.sys.posix.sys.select'. Second, if the file doesn't exist or is moved once watched, the inotifiy instance or the watch descriptor will be invalid and need to be re-initialised. Tip: moving can occur if edited with a text editor. As i found out trying to test inotify by changing a file using vim! That was debug pain! Here is a snippet of code to show how i used it. It's not complete but it shows you how to use the select function and how all the bits fit together. I used an infinite loop because this was part of a daemon that runs forever so you may want to handle that better. /** * Module. */ module common.file.watcher.inotifyengine; /** * Imports. */ import core.sys.linux.sys.inotify; import core.sys.posix.sys.select; import core.sys.posix.unistd; import common.file.logger; import common.file.watcher.engine; import std.string; /** * A class to watch for changes in a file. * * Uses the linux inotify subsystem. */ class INotifyEngine : Engine { /** * The event buffer length. * * This gives us for 1024 events which should be more than enough. */ private enum eventBufferLength = (inotify_event.sizeof + 16) * 1024; /** * The notification flags. * * These are what inotify uses to descriminate on which events to nofify us about. */ private enum notificationFlags = IN_MODIFY | IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_IGNORED; /** * The inotify instance. */ private int _inotifyInstance; /** * The watch descriptor. */ private int _watchDescriptor; /** * The file descriptor set for the select call. */ private fd_set _fileDescriptorSet; /** * The timeout for the select call. */ private timeval _timeout; /** * Constructor. * * Params: * logger = The logger object used to log messages. * * See_Also: * Engine */ public this(Logger logger) { super(logger); } /** * Initialize inotify. * * Throws: * Exception if inotify fails to initialize. */ private void initInotify() { this._inotifyInstance = inotify_init(); if (this._inotifyInstance < 0) { this._logger.error("Inotify failed to initialize."); } this._watchDescriptor = inotify_add_watch(this._inotifyInstance, cast(char*)this._lastFileName.toStringz(), notificationFlags); } /** * Stop inotify. */ private void closeInotify() { inotify_rm_watch(this._inotifyInstance, this._watchDescriptor); close(this._inotifyInstance); } /** * Change the watcher if the file name changes. */ private void checkFileNameChange() { string currentFileName = this.getFileName(); if (currentFileName != this._lastFileName) { this._logger.warning("Watched file name changed to '%s'", currentFileName); this.notify(this._lastFileName); this._lastFileName = currentFileName; this.notify(this._lastFileName); this.closeInotify(); this.initInotify(); this._logger.info("Starting to watch '%s' for alerts (%d, %d)", this._lastFileName, this._inotifyInstance, this._watchDescriptor); } } /** * Retry watching if there was a problem e.g. the file doesn't exist yet. */ private void checkWatchStatus() { if (this._inotifyInstance == -1 || this._watchDescriptor == -1) { this._logger.error("Failed watching '%s' for alerts, retrying...", this._lastFileName); this.closeInotify(); this.initInotify(); this._logger.info("Starting to watch '%s' for alerts (%d, %d)", this._lastFileName, this._inotifyInstance, this._watchDescriptor); } } /** * Check the file for any changes. * * If changes occur then execute the action if one has been assigned. * We are using the select call to perform non blocking event handling waiting for inotify. *
Re: imports and a data structure (any critique welcome)
Jonathan: Thank you. In reply to [1]: that is an interesting issue that I don't really understand right now. Can you explain exactly where I invoke undefined behavior? It can be shown with this function: int*[] foo() { int x; int*[] arr = [&x]; return arr; } Here the value 'x' is allocated on the stack, in the stack frame of the function foo(). arr is a heap-allocated array, so you can return it safely from foo. But arr contains a pointer to x, that points still to the stack frame of foo(). When foo() ends, the stack space used by the stack frame of foo gets reused for other purposes, so now the pointer inside the array arr points to data unrelated to the original x, essentially garbage. It was my understanding that structs are passed and returned by value, and the assignment x = some struct makes a copy of some struct and stores it in x. This is right. Bit the problem is different. Does auto do a simple type inference to find out that Term* should be there? Right. Is there an advantage to using auto? It makes writing the code faster, the code less cluttered, and sometimes the type is "obvious" for the person that reads the code. Just don't abuse it. I can't seem to put @safe: at the top of the file -- is it the same as compiling with -safe. Is there a way to add this as a source annotation? There is a writeln in the main, so you have to use: void main(string[] args) @system { But still the code doesn't compile: temp.d(30): Error: field TermBody.terms cannot be accessed in @safe code because it overlaps with a pointer ... So @safe can't be used here. Is ! an operator in e.g. ADT!q ... ! is the "not" operator, but there it's used to instantiate a template. What is the mixin bit doing? It probably mixes-in (statically) some code generated at compile-time. Can you point me towards any tutorials, or should I buy the book? The book is useful if you want to get serious about learning D. Otherwise the online docs, Rosettacode and the book by a person that posts often in D.learn could suffice. That is odd; I find that D shares a philosophy closer to Haskell than many of the "lower level" languages like C. In D you can write functional-style code, look at Rosettacode D entries for many examples. (Also regarding your first post, D1 language used to have literary programming built-in, as GHC-Haskell, but this feature was dropped in D2). However, this is really *not* an algebraic type since sharing is not algebraic, If you share something that is immutable, and you assure there are no null pointers, then the fact that is shared is transparent, so why is it not algebraic? The only reason I didn't use an object oriented approach off the bat is that I don't think I completely understand when to use a struct versus an object. Using structs seem to fit the story better, because the structure isn't really emitting any functionality, I just want to perform some functions to it. So using structs feel like a better fit. Feel free to correct me here. What are some of the drawbacks to using object. How much more time overhead is there once the object is created? Class instances have some overhead, +2 words of memory, plus a bit of time to initialize those fields. Class instances allocated on the heap are a bit simpler to use compared to structs handled by pointers. You are right, I probably look like an idiomless noob! I totally am! Don't worry, you are going to learn. (there is quite a lot of syntax in D). D is a system language designed to be simpler to use, and it tries to be safer, and it tries to have many of the most useful tools. All this leads to a complex language. And the syntax reflects the varied semantics of all the things it contains. It's not just syntax sugar of the same bits of lambda calculus. For now, can you tell me what I could do better about the switch statement That switch can become an array. Or you can use enumerations with "final switch", and so on. and what is wrong with (*term).node? D is a bit smarter than C, so "term.node" suffices. Bye, bearophile
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 11:56:08 UTC, Ali Çehreli wrote: However, __FILE__ happens to be the current source file that is being compiled but I think the OP wants the current compilation directory. Being a C library file, getcwd() does not work at compile time: import std.stdio; void main() { import std.path: dirName; enum compiledFile = __FILE__; writeln(compiledFile); static const compileTime = __DATE__ ~ " " ~ __TIME__; writeln(compileTime); /* import std.file: getcwd; static const compilationDir = getcwd(); writeln(compilationDir); Error: getcwd cannot be interpreted at compile time, because it has no available source code */ } Ali Yes, just like what Ali said above, __FILE__, __DATE__ and __TIME__ do work for their respective usages, but I'm also looking for a way to get the current compilation directory during compile time, and getcwd() doesn't seem to be working. Isn't there something like __DIR__ or __PATH__ that I can use to get that information? -Ravn-
Re: getting __DIR__ and __TIME__ of compilation?
On 12/27/2013 03:51 AM, Lemonfiend wrote: > module main; > > import std.stdio; > > enum file = __FILE__; > enum time = __TIME__; > > void main() > { > writeln(file); > writeln(time); > } > > This works for me. And the reason is D's CTFE: Anything that needs to be and can to be evaluated at compile time is evaluated at compile time. Since manifest constants and the initial values of static constants must be known at compile time both enum and 'static const' will work. However, __FILE__ happens to be the current source file that is being compiled but I think the OP wants the current compilation directory. Being a C library file, getcwd() does not work at compile time: import std.stdio; void main() { import std.path: dirName; enum compiledFile = __FILE__; writeln(compiledFile); static const compileTime = __DATE__ ~ " " ~ __TIME__; writeln(compileTime); /* import std.file: getcwd; static const compilationDir = getcwd(); writeln(compilationDir); Error: getcwd cannot be interpreted at compile time, because it has no available source code */ } Ali
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 08:57:02 UTC, Ravn wrote: On Friday, 27 December 2013 at 07:31:19 UTC, nazriel wrote: On Friday, 27 December 2013 at 06:39:54 UTC, Ravn wrote: Hi, I'm trying get the directory path and time at which the compilation was made (not when the program is run), something similar like this example in Haxe http://haxe.org/manual/macros#macro-functions Is it possible to do so in D? Something like __DIR__ and __DATE__ or __TIME__ in D traits maybe? ( http://dlang.org/traits.html#specialkeywords ) Thanks in advance -Ravn- Hello. Maybe this will work for you? http://dpaste.dzfl.pl/3ad4aa3a --- void main() { import std.path: dirName; pragma(msg, dirName(__FILE__) ~ " " ~ __DATE__ ~ " " ~ __TIME__); } --- Hi, thanks for the answer, I've tried your solution, but I need to store the path and time to be used for various stuffs later, not just during errors, maybe something closer to this, Example: file located at D:\misc\hello.d if there's a code like this // inside hello.d void main() { string path = getAbsolutePath(); string date_and_time = getDateAndTime(); } I would like the compiler to specifically process the return value of getAbsolutePath() as well as getDateAndTime during compile time. So that whenever I run the program, its as if the code above is written and compiled as the following code, // inside hello.d void main() { string path = "D:\misc\"; string date_and_time = "Dec 2x 20xx hh:mm:ss"; } Would that be possible? -Ravn- module main; import std.stdio; enum file = __FILE__; enum time = __TIME__; void main() { writeln(file); writeln(time); } This works for me.
Re: inotify and recursion
On 12/27/13 04:23, David Eagen wrote: > void main() > { > string filename="aaa"; > > int inotfd = inotify_init(); > int watch_desc = inotify_add_watch(inotfd, toStringz(filename), > IN_MODIFY); > > size_t bufsiz = inotify_event.sizeof + PATH_MAX + 1; > inotify_event* event = cast(inotify_event *) malloc(bufsiz); > > /* wait for an event to occur */ > read(inotfd, event, event.sizeof); You probably meant read(inotfd, event, (*event).sizeof); but in this case the inotify_event structure contains an optional trailing buffer, so it should be read(inotfd, event, bufsiz); artur
Re: Which Libraries?
Am Fri, 27 Dec 2013 07:00:29 + schrieb "Rikki Cattermole" : > On Friday, 27 December 2013 at 05:00:30 UTC, Josh Phillips wrote: > > I was wondering if people could suggest which libraries may be > > best to use for building an application which would be a type of > > text editor with multiple documents and branches. I need > > something whereby I can create simple, custom windows and do > > simple text editing, but then i need it to also handle much more > > complicated graphics in a 3D viewport looking at lots of > > branching documents. I'm not quite sure if something like GtkD > > or > > QtD can handle the more complicated graphics or not, or if it is > > possible to build it with windows, or perhaps trying to make a > > text editor with opengl. I've been looking into different ideas > > and thought i'd try and ask for some advice. > > GtkD and QtD are both bindings to my knowledge so they should > have the same power as the library itself. > If you choose to go the route of making a gui lib yourself. Would > you be kind enough to look at mine (DOOGLE[1]). I could use some > help if you want to go that way. > > There is also DQuick and DWT. > > [1] https://github.com/rikkimax/DOOGLE/wiki/Roadmap GtkD has OpenGL support -- Marco
Re: Reading file by line, weird result
Am Fri, 27 Dec 2013 10:24:15 + schrieb "Dfr" : > On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote: > > The solution is to append `line.dup` instead of `line`. > > > > I guess this note in the documentation should be marked red: > >> Each front will not persist after popFront is called, so the > >> caller must copy its contents (e.g. by calling to!string) if > >> retention is needed. > > Thank you, .dup helped. To avoid allocating new memory for each line of text, byLine reuses the buffer. You are supposed to make a duplicate if you plan to keep it. It would be different if you had: string s; foreach (line; frange) { s ~= line } in which case, the _contents_ of the line buffer, not the buffer itself are appended to the string s. -- Marco
Re: Reading file by line, weird result
On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote: The solution is to append `line.dup` instead of `line`. I guess this note in the documentation should be marked red: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed. Thank you, .dup helped.
Re: Reading file by line, weird result
The solution is to append `line.dup` instead of `line`. I guess this note in the documentation should be marked red: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed.
Reading file by line, weird result
Hello, here is simple pice of code to read text file into array of lines: import std.stdio; void main(string args[]) { auto file = File(args[1]); auto frange = file.byLine(); char[][] buf; foreach (char[] line; frange) { buf = buf ~ line; } writeln(buf); } When i run this code for this text file: --cutline--- hello world of D and have a nice day --cutline--- then program prints: ["and\n\n", "and\n\n", "and\n", "and", "have a nice day!"] As you can see, this is complete madness, any idea what is wrong here ?
Re: getting __DIR__ and __TIME__ of compilation?
On Friday, 27 December 2013 at 07:31:19 UTC, nazriel wrote: On Friday, 27 December 2013 at 06:39:54 UTC, Ravn wrote: Hi, I'm trying get the directory path and time at which the compilation was made (not when the program is run), something similar like this example in Haxe http://haxe.org/manual/macros#macro-functions Is it possible to do so in D? Something like __DIR__ and __DATE__ or __TIME__ in D traits maybe? ( http://dlang.org/traits.html#specialkeywords ) Thanks in advance -Ravn- Hello. Maybe this will work for you? http://dpaste.dzfl.pl/3ad4aa3a --- void main() { import std.path: dirName; pragma(msg, dirName(__FILE__) ~ " " ~ __DATE__ ~ " " ~ __TIME__); } --- Hi, thanks for the answer, I've tried your solution, but I need to store the path and time to be used for various stuffs later, not just during errors, maybe something closer to this, Example: file located at D:\misc\hello.d if there's a code like this // inside hello.d void main() { string path = getAbsolutePath(); string date_and_time = getDateAndTime(); } I would like the compiler to specifically process the return value of getAbsolutePath() as well as getDateAndTime during compile time. So that whenever I run the program, its as if the code above is written and compiled as the following code, // inside hello.d void main() { string path = "D:\misc\"; string date_and_time = "Dec 2x 20xx hh:mm:ss"; } Would that be possible? -Ravn-