Re: pu$�le
== Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > On Saturday 17 July 2010 22:10:07 strtr wrote: > > == Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > > > > > On Saturday 17 July 2010 18:59:18 strtr wrote: > > > > That is [dollar sign, euro sign] > > > > > > > > The reason I post it is because I expected the stash to be 3 lower. > > > > > > Well, if I replace writef with write, I get > > > I made $€8. > > > If I leave in the writef though, I get this error: > > > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/ > st > > > di o.d(623): > > > Error: static assert "You must pass a formatting string as the first > > > argum ent to > > > writef or writefln. If no formatting is needed, you may want to use wri > te > > > o r > > > writeln." > > > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/ > st > > > di o.d(1442): > > > instantiated from here: writef!(const(char)) > > > t.d(18):instantiated from here: writef!(const(char)) > > > I'm not quite sure why you're using writef here since writef requires a > > > str ing > > > as its first argument, and you're passing it something other than a > > > string as the > > > first argument. > > > - Jonathan M Davis > > > > Or you have an awesome D emulator in your brain, or you cheated by actual > ly > > running the code ;P > Cheated? I thought that you were trying to figure out why the code wasn't d > oing > what you expected it to be doing. So, of course I ran it. > Though, it's more likely that I have an x86 emulator in my brain which can > run > dmd than that I have a D emulator in my brain if I figured this out in my h > ead, > since I gave you the exact error message that dmd does. > - Jonathan M Davis I don't find it more likely that you have a x86 emulator in your brain which then ran dmd to compile some code. I might even think that almost impossible ;P If you knew the compiler well enough you might be capable of giving that error message with only the extra knowledge of where your files recite and version and OS infos.
Re: pu$�le
== Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > On Saturday 17 July 2010 21:48:30 strtr wrote: > > == Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > > > > > On Saturday 17 July 2010 18:59:18 strtr wrote: > > > > That is [dollar sign, euro sign] > > > > > > > > The reason I post it is because I expected the stash to be 3 lower. > > > > > > As to why it's not working right, change th foreach loop to this: > > > foreach(dchar coin; coins) > > > { > > > ... > > > } > > > Otherwise, instead of looping over each code point, you're looping over > > > each code unit. char[] and string are encoded in utf-8, so each char is > > > a code unit, and 1 - 4 code units are put together to form a code point, > > > which is what you'd normally think of as a character. > > > The dollar sign takes one code unit in utf-8, but the euro sign takes 3. > > > So, you're looping 4 times instead of 2. By specifying dchar, the > > > compiler automatically processes the code units correctly to make it so > > > that you loop over each code point (i.e. character) rather than each > > > code unit (i.e. char). You should pretty much never deal with each > > > individual char or wchar in a string or wstring. Do the conversion to > > > dchar or dstring if you want to access individual characters. You can > > > also use std.utf.stride() to iterate over to the next code unit which > > > starts a code point, but you're still going to have to make sure that > > > you convert it to a dchar to process it properly. Otherwise, only ASCII > > > characters will work right (since they fit in a single code unit). > > > Fortunately, foreach takes care of all this for is if we specify the > > > element type as dchar. > > > As for why it's 4 rather than 2 in the corrected version (or 8 instead of > > > 4 in the incorrect version), that's because you have both scope(exit) > > > and scop(success) there. Both will be run, so both will increment stash, > > > and you get double the increments that you seem to be expecting. > > > - Jonathan M Davis > > > > Wasn't it obvious the puzzle was about exceptions, with half of the lines > > being scope guards and all? > > Part of the puzzle is the realization that chars aren't code points but > > code units. The other part is understanding the order of scope guard > > execution. I'm not sure whether the linux or the windows version of writef > > is the correct one, but here I get a nice utf-exception. (Or did you maybe > > use D2? if not then we have a discrepancy bug) > All I ever use is D2. I have no idea what D1 would be doing differently. In > D2, > writef(), the "f" is for format or formatted, and you have to have a "format" > string like printf would in order for it to work. write() is the version which > doesn't require a format string. I am using Linux if that changes anything, > but > as far as I can tell, you're using writef() incorrectly. In any case, I > obviously don't quite get what you're trying to do since (at least in D2), I > don't believe that you have any functions in that loop which will every throw > an > exception. If you were using File's writef() because you were writing to a > file, > then that would be different. But writef() by itself is to stdout and won't > throw. > Now, as you're using D1, that may change things. But you gave no indication > that > you were using D1. In future questions, you should probably be more specific > about that, since I think that most people around here are using D2, and they > will likely assume that you're using D2 unless you say otherwise. I certainly > did. > - Jonathan M Davis I think I'll start subject tagging my posts: [D1/D2] std.stdio in D1 doesn't mention a write function and feeding the writef function an illegal UTF string will result in a UTF exception. With this information, what do you think the output should be?
Re: pu$�le
On Saturday 17 July 2010 22:10:07 strtr wrote: > == Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > > > On Saturday 17 July 2010 18:59:18 strtr wrote: > > > That is [dollar sign, euro sign] > > > > > > The reason I post it is because I expected the stash to be 3 lower. > > > > Well, if I replace writef with write, I get > > I made $€8. > > If I leave in the writef though, I get this error: > > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/st > > di o.d(623): > > Error: static assert "You must pass a formatting string as the first > > argum ent to > > writef or writefln. If no formatting is needed, you may want to use write > > o r > > writeln." > > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/st > > di o.d(1442): > > instantiated from here: writef!(const(char)) > > t.d(18):instantiated from here: writef!(const(char)) > > I'm not quite sure why you're using writef here since writef requires a > > str ing > > as its first argument, and you're passing it something other than a > > string as the > > first argument. > > - Jonathan M Davis > > Or you have an awesome D emulator in your brain, or you cheated by actually > running the code ;P Cheated? I thought that you were trying to figure out why the code wasn't doing what you expected it to be doing. So, of course I ran it. Though, it's more likely that I have an x86 emulator in my brain which can run dmd than that I have a D emulator in my brain if I figured this out in my head, since I gave you the exact error message that dmd does. - Jonathan M Davis
Re: pu$�le
On Saturday 17 July 2010 21:48:30 strtr wrote: > == Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > > > On Saturday 17 July 2010 18:59:18 strtr wrote: > > > That is [dollar sign, euro sign] > > > > > > The reason I post it is because I expected the stash to be 3 lower. > > > > As to why it's not working right, change th foreach loop to this: > > foreach(dchar coin; coins) > > { > > ... > > } > > Otherwise, instead of looping over each code point, you're looping over > > each code unit. char[] and string are encoded in utf-8, so each char is > > a code unit, and 1 - 4 code units are put together to form a code point, > > which is what you'd normally think of as a character. > > The dollar sign takes one code unit in utf-8, but the euro sign takes 3. > > So, you're looping 4 times instead of 2. By specifying dchar, the > > compiler automatically processes the code units correctly to make it so > > that you loop over each code point (i.e. character) rather than each > > code unit (i.e. char). You should pretty much never deal with each > > individual char or wchar in a string or wstring. Do the conversion to > > dchar or dstring if you want to access individual characters. You can > > also use std.utf.stride() to iterate over to the next code unit which > > starts a code point, but you're still going to have to make sure that > > you convert it to a dchar to process it properly. Otherwise, only ASCII > > characters will work right (since they fit in a single code unit). > > Fortunately, foreach takes care of all this for is if we specify the > > element type as dchar. > > As for why it's 4 rather than 2 in the corrected version (or 8 instead of > > 4 in the incorrect version), that's because you have both scope(exit) > > and scop(success) there. Both will be run, so both will increment stash, > > and you get double the increments that you seem to be expecting. > > - Jonathan M Davis > > Wasn't it obvious the puzzle was about exceptions, with half of the lines > being scope guards and all? > Part of the puzzle is the realization that chars aren't code points but > code units. The other part is understanding the order of scope guard > execution. I'm not sure whether the linux or the windows version of writef > is the correct one, but here I get a nice utf-exception. (Or did you maybe > use D2? if not then we have a discrepancy bug) All I ever use is D2. I have no idea what D1 would be doing differently. In D2, writef(), the "f" is for format or formatted, and you have to have a "format" string like printf would in order for it to work. write() is the version which doesn't require a format string. I am using Linux if that changes anything, but as far as I can tell, you're using writef() incorrectly. In any case, I obviously don't quite get what you're trying to do since (at least in D2), I don't believe that you have any functions in that loop which will every throw an exception. If you were using File's writef() because you were writing to a file, then that would be different. But writef() by itself is to stdout and won't throw. Now, as you're using D1, that may change things. But you gave no indication that you were using D1. In future questions, you should probably be more specific about that, since I think that most people around here are using D2, and they will likely assume that you're using D2 unless you say otherwise. I certainly did. - Jonathan M Davis
Re: pu$�le
== Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > On Saturday 17 July 2010 18:59:18 strtr wrote: > > That is [dollar sign, euro sign] > > > > The reason I post it is because I expected the stash to be 3 lower. > Well, if I replace writef with write, I get > I made $€8. > If I leave in the writef though, I get this error: > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/stdi > o.d(623): > Error: static assert "You must pass a formatting string as the first argum > ent to > writef or writefln. If no formatting is needed, you may want to use write o > r > writeln." > /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/stdi > o.d(1442): > instantiated from here: writef!(const(char)) > t.d(18):instantiated from here: writef!(const(char)) > I'm not quite sure why you're using writef here since writef requires a str > ing > as its first argument, and you're passing it something other than a string > as the > first argument. > - Jonathan M Davis Or you have an awesome D emulator in your brain, or you cheated by actually running the code ;P
Re: pu$�le
== Quote from Jonathan M Davis (jmdavisp...@gmail.com)'s article > On Saturday 17 July 2010 18:59:18 strtr wrote: > > That is [dollar sign, euro sign] > > > > The reason I post it is because I expected the stash to be 3 lower. > As to why it's not working right, change th foreach loop to this: > foreach(dchar coin; coins) > { > ... > } > Otherwise, instead of looping over each code point, you're looping over each > code unit. char[] and string are encoded in utf-8, so each char is a code > unit, > and 1 - 4 code units are put together to form a code point, which is what > you'd > normally think of as a character. > The dollar sign takes one code unit in utf-8, but the euro sign takes 3. So, > you're looping 4 times instead of 2. By specifying dchar, the compiler > automatically processes the code units correctly to make it so that you loop > over each code point (i.e. character) rather than each code unit (i.e. char). > You should pretty much never deal with each individual char or wchar in a > string > or wstring. Do the conversion to dchar or dstring if you want to access > individual characters. You can also use std.utf.stride() to iterate over to > the > next code unit which starts a code point, but you're still going to have to > make > sure that you convert it to a dchar to process it properly. Otherwise, only > ASCII characters will work right (since they fit in a single code unit). > Fortunately, foreach takes care of all this for is if we specify the element > type as dchar. > As for why it's 4 rather than 2 in the corrected version (or 8 instead of 4 in > the incorrect version), that's because you have both scope(exit) and > scop(success) there. Both will be run, so both will increment stash, and you > get > double the increments that you seem to be expecting. > - Jonathan M Davis Wasn't it obvious the puzzle was about exceptions, with half of the lines being scope guards and all? Part of the puzzle is the realization that chars aren't code points but code units. The other part is understanding the order of scope guard execution. I'm not sure whether the linux or the windows version of writef is the correct one, but here I get a nice utf-exception. (Or did you maybe use D2? if not then we have a discrepancy bug)
Re: pu$�le
On Saturday 17 July 2010 18:59:18 strtr wrote: > That is [dollar sign, euro sign] > > The reason I post it is because I expected the stash to be 3 lower. As to why it's not working right, change th foreach loop to this: foreach(dchar coin; coins) { ... } Otherwise, instead of looping over each code point, you're looping over each code unit. char[] and string are encoded in utf-8, so each char is a code unit, and 1 - 4 code units are put together to form a code point, which is what you'd normally think of as a character. The dollar sign takes one code unit in utf-8, but the euro sign takes 3. So, you're looping 4 times instead of 2. By specifying dchar, the compiler automatically processes the code units correctly to make it so that you loop over each code point (i.e. character) rather than each code unit (i.e. char). You should pretty much never deal with each individual char or wchar in a string or wstring. Do the conversion to dchar or dstring if you want to access individual characters. You can also use std.utf.stride() to iterate over to the next code unit which starts a code point, but you're still going to have to make sure that you convert it to a dchar to process it properly. Otherwise, only ASCII characters will work right (since they fit in a single code unit). Fortunately, foreach takes care of all this for is if we specify the element type as dchar. As for why it's 4 rather than 2 in the corrected version (or 8 instead of 4 in the incorrect version), that's because you have both scope(exit) and scop(success) there. Both will be run, so both will increment stash, and you get double the increments that you seem to be expecting. - Jonathan M Davis
Re: pu$�le
On Saturday 17 July 2010 18:59:18 strtr wrote: > That is [dollar sign, euro sign] > > The reason I post it is because I expected the stash to be 3 lower. Well, if I replace writef with write, I get I made $â¬8. If I leave in the writef though, I get this error: /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/stdio.d(623): Error: static assert "You must pass a formatting string as the first argument to writef or writefln. If no formatting is needed, you may want to use write or writeln." /home/jmdavis/Downloaded_Files/dmd/dmd2/linux/bin/../../src/phobos/std/stdio.d(1442): instantiated from here: writef!(const(char)) t.d(18):instantiated from here: writef!(const(char)) I'm not quite sure why you're using writef here since writef requires a string as its first argument, and you're passing it something other than a string as the first argument. - Jonathan M Davis
Re: Equivalent of scanf
On Saturday 17 July 2010 16:21:04 Michael Koehmstedt wrote: > Thanks for the informative reply. > > I am getting a run-time error with to!int(str). Apparently to!() seems to > only support one-way converting other types to strings. That is part of > the reason why I was getting so confused in figuring out how to read in an > integer value. But you guys pointed me towards parse!() and that does work > with string->int. Hmm... to!int(str) seems to be working for me. The issue is probably that when doing such a conversion, the _whole_ string must be convertable. So, no extra whitespace or whatnot. If you're looking to take multiple values out of a particular string or you might have whitespace in it, parse() is a better choice. But to() should work just fine as long as the string is exactly convertable to the type. As I understand it, to() should be able to convert pretty much anything to anything as long as the type has the appropriate conversion functions defined. - Jonathan M Davis
Re: Equivalent of scanf
On Saturday 17 July 2010 16:35:11 torhu wrote: > On 18.07.2010 01:21, Michael Koehmstedt wrote: > > > > So there is no scanf equivalent, but there is also nothing similar to C++ > > cin with the<< operator? > > Equivalents of those are available in std.stream and std.cstream, but > those modules will probably go away in a while. We'll be getting new streams which are range based which may or may not use the name std.stream, but the current implementation is certainly going away. Like a number in things in Phobos right now, it's being updated and replaced with something better. Phobos is evolving for the better, and it's great to see that it's finally starting to come together. - Jonathan M Davis
Re: pu$�le
That is [dollar sign, euro sign] The reason I post it is because I expected the stash to be 3 lower.
pu$�le
What does this program print? const char[] coins = `$�`; void main() { writef(`I made `); int stash = 0; scope(exit) writefln(stash,`.`); scope(failure) stash--; foreach(coin;coins) { scope(exit) stash++; scope(success) stash++; scope(failure) stash--; scope(failure) continue; writef(coin); } }
Re: CT usage only in executable
== Quote from torhu (n...@spam.invalid)'s article > On 15.07.2010 02:29, strtr wrote: > > Not that the memory is really significant compared to the rest of my > > program, > > but I have a few fairly large arrays I use only in compile time and I was > > wondering why dmd still includes those in the executable (simple text search > > dug them up). > As a workaround you could try putting those arrays in a separate module > which you don't link into your executable. If you use a build tool like > xfbuild, you can exclude files with the -X switch. CTFE would still work. Thanks, I'll try that if dmd will not do this as well before my program is finished :)
Re: Equivalent of scanf
On 18.07.2010 01:21, Michael Koehmstedt wrote: So there is no scanf equivalent, but there is also nothing similar to C++ cin with the<< operator? Equivalents of those are available in std.stream and std.cstream, but those modules will probably go away in a while.
Re: Equivalent of scanf
Thanks for the informative reply. I am getting a run-time error with to!int(str). Apparently to!() seems to only support one-way converting other types to strings. That is part of the reason why I was getting so confused in figuring out how to read in an integer value. But you guys pointed me towards parse!() and that does work with string->int. So there is no scanf equivalent, but there is also nothing similar to C++ cin with the << operator? And as for Phobos not being included much in TDPL, makes sense. I hope they include a reference section on it in the 2nd edition after Phobos is stabilized. That would make the book near perfect imo.
Re: Equivalent of scanf
== Quote from Michael Koehmstedt (mkoehmst...@runner.csub.edu)'s article > So there is no scanf equivalent, but there is also nothing similar to C++ cin > with > the << operator? I meant the >> operator, of course. *slaps forehead*
Re: Equivalent of scanf
On Saturday 17 July 2010 15:41:14 Michael Koehmstedt wrote: > I'm having trouble figuring out how to do formatted console input, > something like C scanf() or C++ templated stream input. Unfortunately, > console input isn't covered in much detail in TDPL book. There doesn't > appear to be much discussion about the standard library at all, which was > a bit disappointing. > > But anyway, what different ways are there to properly do input from the > console? Fetching a string with readln() is easy enough, but how could I > fetch, say, an integer value? Conversely, what is the preferred method for > converting string into integer or floating point values? > > Thanks, > Michael Parsing strings like that isn't something that I've done much of lately, so I don't know what the best way to do it in D is. However, std.conv has essentially what you're looking for. For most conversions, just use to!T() - e.g. to!int(str) will convert the string str into an int and to!string(i) will convert the integer i to a string. For more complicated parsing, there's parse!T() which does essentially the same thing except that instead of converting the whole string, it only converts the portion which makes sense and leaves the rest. e.g. string test = "123 \t 76.14"; auto a = parse!(uint)(test); assert(a == 123); assert(test == " \t 76.14"); So, with multiple calls to parse, you can parse the string. I'm not aware of a way to do it in manner like sscanf though, where you parse it all in one command. Worse comes to worse, if you really want that, you can always use C's sscanf and it'll work. TDPL purposely didn't touch on Phobos much. One reason for this is because it was focusing on the language itself rather than whatever libraries there might be. The other main reason, as I understand it, is that Phobos has been in too much flux to have put in TDPL. A lot of work has been done on Phobos in the past few months, and TDPL was already turned in to the editor. And a lot of work continues to be done on Phobos. So, anything that was put in TPDL on Phobos would either have constrained Phobos so that it couldn't change when it needed to or would have made it so that TDPL didn't match Phobos - either that or we would have had to wait longer for TDPL. - Jonathan M Davis
Re: Equivalent of scanf
On 18.07.2010 00:41, Michael Koehmstedt wrote: I'm having trouble figuring out how to do formatted console input, something like C scanf() or C++ templated stream input. Unfortunately, console input isn't covered in much detail in TDPL book. There doesn't appear to be much discussion about the standard library at all, which was a bit disappointing. But anyway, what different ways are there to properly do input from the console? Fetching a string with readln() is easy enough, but how could I fetch, say, an integer value? Conversely, what is the preferred method for converting string into integer or floating point values? The standard library (Phobos) is getting overhauled, which is probably why there's not a lot of detail about it in the book. It's still quite limited and buggy. Up until now, most real D work has probably been done using D1 and the Tango library. There's a scanf implementation in the works, but it's not released yet. You can probably get by with the to() and parse() functions in std.conv. C's isdigit() will probably come in handy too, it's defined in core.stdc.ctype.
Equivalent of scanf
I'm having trouble figuring out how to do formatted console input, something like C scanf() or C++ templated stream input. Unfortunately, console input isn't covered in much detail in TDPL book. There doesn't appear to be much discussion about the standard library at all, which was a bit disappointing. But anyway, what different ways are there to properly do input from the console? Fetching a string with readln() is easy enough, but how could I fetch, say, an integer value? Conversely, what is the preferred method for converting string into integer or floating point values? Thanks, Michael
Re: CT usage only in executable
On 15.07.2010 02:29, strtr wrote: Not that the memory is really significant compared to the rest of my program, but I have a few fairly large arrays I use only in compile time and I was wondering why dmd still includes those in the executable (simple text search dug them up). As a workaround you could try putting those arrays in a separate module which you don't link into your executable. If you use a build tool like xfbuild, you can exclude files with the -X switch. CTFE would still work.