Re: Function signature constraint syntax
void func(alias G)(object O) if (is(typeof(G(O)) == void)) { "H. S. Teoh" wrote in message news:mailman.295.1328245356.25230.digitalmars-d-le...@puremagic.com... > Quick question: I have a function that takes an alias parameter: > > struct X { ... }; > > void func(alias G)(object O) { > ... > X x = ...; > G(x); > ... > } > > How do I write a signature constraint that essentially specifies that G > should take a parameter of type X and return void? > > > T > > -- > When solving a problem, take care that you do not become part of the > problem.
Re: Function signature constraint syntax
> > Quick question: I have a function that takes an alias parameter: > >struct X { ... }; > >void func(alias G)(object O) { >... >X x = ...; >G(x); >... >} > > How do I write a signature constraint that essentially specifies that G > should take a parameter of type X and return void? if ( is(typeof(G(X.init ) ) == void)) For the expression to work, G must accept an X and return a void.
Function signature constraint syntax
Quick question: I have a function that takes an alias parameter: struct X { ... }; void func(alias G)(object O) { ... X x = ...; G(x); ... } How do I write a signature constraint that essentially specifies that G should take a parameter of type X and return void? T -- When solving a problem, take care that you do not become part of the problem.
Re: How far can CTFE go?
H. S. Teoh wrote: > I don't think that should be grounds to get rid of CTFE, > though. In contrast to your remark, I do not see the benefits of reducing two compiling phases to one. For me CTFE ist nothing else than running the executables of a first compilation in order to get some values needed for a second compilation. -manfred
Re: How far can CTFE go?
On Fri, Feb 03, 2012 at 12:51:51AM +, Manfred Nowak wrote: > H. S. Teoh wrote: > > > the ideal situation would be that CTFE can replace writing an > > arbitrarily complex helper program > > Aebitrary complex helper programs may include viruses and other nice > surprises. Walter does not want that adminstrators have to worry about > a compilation step to torture the system in such a way. [...] Well, random source code you downloaded over the internet may contain trojans with embedded viruses, so I don't think CTFE would make this problem any worse. You *are* running the virus either way, whether it's compiling the helper programs first and running them (e.g., by running the makefile or build script), or having the compiler run the virus via CTFE. Plus, if you're worried about CTFE being abused to cause problems with the machine it's being compiled on, the current implementation already suffers from the halting problem: the compiler cannot tell whether a CTFE function will ever terminate. It could simply just keep consuming more and more compiler resources (say, by continually appending to an array) until memory is exhausted. And we all know the halting problem is unsolvable. I don't think that should be grounds to get rid of CTFE, though. T -- Кто везде - тот нигде.
linker @ meaning and how to compile static libs
Hi, I am compiling parts of the 7zip SDK (the 7zDec.exe) as a static lib. I am having issues with compile a static lib (from c code, using dmc 8.50) that I can use with D v1.072. The main question is how do I either compile the library with the right version suffix (@12) Or get the linker to use the right version suffix (@8) Generate Lib dmc -o -c ..\src\7zAlloc.c ... xxx.c lib -c 7z.lib bin\7zAlloc.obj ... xxx.obj lib contents: _main7zDec@8 compile and link with .d: xfbuild sevenz.d 7z.lib +o7zDec.exe +D=.deps +O=.objs +full +v +R -release -O -inline -L/M -version=Unicode -version=Tango -L/SUBSYSTEM:console:5 OPTLINK (R) for Win32 Release 8.00.12 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html .objs\sevenz.obj(sevenz) Error 42: Symbol Undefined _main7zDec@12 --- errorlevel 1 From Kim
Re: How far can CTFE go?
H. S. Teoh wrote: > the ideal situation would be that CTFE can replace writing an > arbitrarily complex helper program Aebitrary complex helper programs may include viruses and other nice surprises. Walter does not want that adminstrators have to worry about a compilation step to torture the system in such a way. Which restrictions may supress such torture seems unknown. -manfred
Re: Segment violation (was Re: Why I could not cast string to int?)
On Thu, Feb 02, 2012 at 03:26:52PM -0800, Ali Çehreli wrote: > > On 02/02/2012 03:10 PM, Timon Gehr wrote: > > > LList!ulong fib(){ > > LList!ulong r; > > r=cons(st(1UL),cons(st(1UL),lz(()=>zipWith((Lazy!ulong a, Lazy!ulong > > b)=>lz(()=>a+b),r,r.tail)(; > > return r; > > } > > Sorry, wrong newsgroup. alt.comp.lang.perl is around the corner. :p [...] You mean alt.comp.lang.lisp. :-) T -- Why waste time learning, when ignorance is instantaneous? -- Hobbes, from Calvin & Hobbes
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/02/2012 03:10 PM, Timon Gehr wrote: > LList!ulong fib(){ > LList!ulong r; > r=cons(st(1UL),cons(st(1UL),lz(()=>zipWith((Lazy!ulong a, Lazy!ulong > b)=>lz(()=>a+b),r,r.tail)(; > return r; > } Sorry, wrong newsgroup. alt.comp.lang.perl is around the corner. :p Ali
Re: Segment violation (was Re: Why I could not cast string to int?)
On Fri, Feb 03, 2012 at 12:10:01AM +0100, Timon Gehr wrote: [...] > LList!ulong fib(){ > LList!ulong r; > r=cons(st(1UL),cons(st(1UL),lz(()=>zipWith((Lazy!ulong a, > Lazy!ulong b)=>lz(()=>a+b),r,r.tail)(; > return r; > } Whoa. A caching recursive definition of fibonacci. Impressive! Now I wonder if we can do this with the Ackermann function... ;-) T -- "640K ought to be enough" -- Bill G., 1984. "The Internet is not a primary goal for PC usage" -- Bill G., 1995. "Linux has no impact on Microsoft's strategy" -- Bill G., 1999.
Re: Segment violation (was Re: Why I could not cast string to int?)
On Thursday, February 02, 2012 18:17:36 bearophile wrote: > Timon Gehr: > > This is not a tail-recursive function. And neither is recFactorial, my > > bad. Anyway, my point was that the compiler should not generate code > > that blows up on a (in principle) perfectly sane implementation. > > Is it possible to create a function attribute like @tail_recursive that > produces a compile error if you apply it to a function that's not > tail-recursive? I suspect that Walter would feel the same way about that that he feels about something like marking functions as inline - i.e. that sort of thing should be left up to the compiler to optimize or not as it sees appropriate. - Jonathan M Davis
How far can CTFE go?
I'm experimenting with pluggable expression parser modules, and I'm wondering if I can use CTFE to build parser tables and such. What are the current limitations of CTFE? Are dynamic arrays of structs supported? Associative arrays? What about compile-time cross-module initialization? The idea is to have a library of modules that parse different kinds of expressions, and depending on which subset of modules are actually imported into the main program, the capability of the generated parser will vary. E.g., the basic parser understands only scalar expressions; import the vector module and it gets extended to handle vector expressions; import another module and it understands other kinds of expressions (matrices, etc.). The parser will be fully specified at compile-time (I'm not planning to support dynamically loading parsing modules), so ideally this should be possible to handle using CTFE. Or is this just a fool's errand? On another level, how far are we expecting CTFE to go eventually? In my mind, the ideal situation would be that CTFE can replace writing an arbitrarily complex helper program that generates D code (either functions or data, etc.) which then gets incorporated into the main program. T -- Guns don't kill people. Bullets do.
Re: Segment violation (was Re: Why I could not cast string to int?)
On Thursday, February 02, 2012 18:14:25 bearophile wrote: > xancorreu: > > But you "only" put a "in" in > > recFactorial function argument. What this mean? **Why** this is more > > efficient than mine? > > It wasn't meant to improve performance. "in" turns a function argument to > "input only" (and eventually scoped too). Generally when you program in D2 > it's a good practice to use immutability where you can and where this > doesn't cause other performance or typing problems. Immutability avoids > bugs, allows a stronger purity (and I have seen DMD is often able to > compiler a little more efficient program if you use immutability/constants > everywhere they are a good fit). So 95% of the arguments of your program > are better tagged with "in". in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. - Jonathan M Davis
Re: Segment violation (was Re: Why I could not cast string to int?)
Timon Gehr: > This is not a tail-recursive function. And neither is recFactorial, my > bad. Anyway, my point was that the compiler should not generate code > that blows up on a (in principle) perfectly sane implementation. Is it possible to create a function attribute like @tail_recursive that produces a compile error if you apply it to a function that's not tail-recursive? Bye, bearophile
Re: Segment violation (was Re: Why I could not cast string to int?)
xancorreu: > But you "only" put a "in" in > recFactorial function argument. What this mean? **Why** this is more > efficient than mine? It wasn't meant to improve performance. "in" turns a function argument to "input only" (and eventually scoped too). Generally when you program in D2 it's a good practice to use immutability where you can and where this doesn't cause other performance or typing problems. Immutability avoids bugs, allows a stronger purity (and I have seen DMD is often able to compiler a little more efficient program if you use immutability/constants everywhere they are a good fit). So 95% of the arguments of your program are better tagged with "in". Bye, bearophile
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/02/2012 11:47 PM, H. S. Teoh wrote: On Thu, Feb 02, 2012 at 10:55:06PM +0100, Timon Gehr wrote: On 02/02/2012 08:04 PM, xancorreu wrote: [...] For the other hand, how can increase the stack in linux? [...] I don't know, but it is best to just rewrite the code so that it does not use recursion. (This kind of problem is exactly the reason why any language standard should mandate tail call optimization.) Doesn't help badly-chosen implementations like: int fib(int n) { if (n<= 2) return 1; else return fib(n-2) + fib(n+1); } This is not a tail-recursive function. And neither is recFactorial, my bad. Anyway, my point was that the compiler should not generate code that blows up on a (in principle) perfectly sane implementation. There's not much the compiler can do to offset programmers choosing the wrong algorithm for the job. Agreed. It can't replace educating programmers to not implement things a certain way unless they have to. T Or unless they feel like it. LList!ulong fib(){ LList!ulong r; r=cons(st(1UL),cons(st(1UL),lz(()=>zipWith((Lazy!ulong a, Lazy!ulong b)=>lz(()=>a+b),r,r.tail)(; return r; }
Re: Segment violation (was Re: Why I could not cast string to int?)
On Thu, Feb 02, 2012 at 02:47:22PM -0800, H. S. Teoh wrote: [...] > int fib(int n) { > if (n <= 2) return 1; > else return fib(n-2) + fib(n+1); [...] Ugh. That should be fib(n-1), not fib(n+1). But no matter, such a thing shouldn't ever be actually written and compiled, as Andrei says. :) T -- Change is inevitable, except from a vending machine.
Re: Segment violation (was Re: Why I could not cast string to int?)
On Thu, Feb 02, 2012 at 10:55:06PM +0100, Timon Gehr wrote: > On 02/02/2012 08:04 PM, xancorreu wrote: [...] > >For the other hand, how can increase the stack in linux? [...] > > I don't know, but it is best to just rewrite the code so that it does > not use recursion. > > (This kind of problem is exactly the reason why any language standard > should mandate tail call optimization.) Doesn't help badly-chosen implementations like: int fib(int n) { if (n <= 2) return 1; else return fib(n-2) + fib(n+1); } There's not much the compiler can do to offset programmers choosing the wrong algorithm for the job. It can't replace educating programmers to not implement things a certain way unless they have to. T -- Philosophy: how to make a career out of daydreaming.
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/02/2012 05:28 PM, xancorreu wrote: I get "segment violation" error with ./factorial 40 How can I resolve it? My code is: import std.stdio, std.bigint, std.string, std.conv, std.stream; BigInt recFactorial(int n) { if (n == 0) return BigInt(1); else return (BigInt(n) * recFactorial(n - 1)); } void main(string[] args) { if (args.length != 2) writeln("Factorial requires a number"); else try { writeln(recFactorial(std.conv.to!int(args[1]))); } catch { writeln("Error"); } } Thanks a lot, import std.stdio, std.bigint, std.conv; BigInt factorial(int n) { BigInt result=1; foreach(i;1..n) result*=i; return result; } void main(string[] args) { if (args.length != 2) writeln("Factorial requires a number"); else try { writeln(factorial(std.conv.to!int(args[1]))); } catch { writeln("Error"); } }
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/02/2012 08:04 PM, xancorreu wrote: Al 02/02/12 19:30, En/na bearophile ha escrit: xancorreu: I get "segment violation" error with ./factorial 40 How can I resolve it? You are having a stack overflow. DMD currently doesn't print a good message because of this regression that is being worked on: http://d.puremagic.com/issues/show_bug.cgi?id=6088 On Windows with DMD you increase the stack like this: dmd -L/STACK:1 -run test2.d 40> result.txt If it goes in overflow still, increase the stack some more. But it will take a long time to compute the result even with the latest 2.058head with improved GC because the algorithm you have used to compute the factorial is very bad. I have rewritten your code like this: import std.stdio, std.bigint, std.conv, std.exception; BigInt recFactorial(in int n) { if (n == 0) return BigInt(1); else return BigInt(n) * recFactorial(n - 1); } void main(string[] args) { if (args.length != 2) { writeln("Factorial requires a number."); } else { try { writeln(recFactorial(to!int(args[1]))); } catch (ConvException e) { writeln("Error"); } } } Note the usage of ConvException, it's a very good practice to never use a generic "gotta catch them all" expression, because it leads to hiding other bugs in your code, and this is a source for troubles. Bye, bearophile Thank you very much for recode this. But you "only" put a "in" in recFactorial function argument. What this mean? **Why** this is more efficient than mine? It is not. He just added some stylistic changes that don't change the code's semantics in any way. For the other hand, how can increase the stack in linux? Thanks, Xan. I don't know, but it is best to just rewrite the code so that it does not use recursion. (This kind of problem is exactly the reason why any language standard should mandate tail call optimization.)
Re: i18n
On 02/02/2012 18:48, xancorreu wrote: Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) Is this just about supporting different human languages in your app? You can put the strings output by your app in a separate file or in a section within the code file to which they apply, and use either version blocks (compile-time) or arrays (run-time) to choose between them. Under Windows, you can use a stringtable resource. It's possible to make resources language-specific, but I don't know how. Stewart.
Re: Why I could not cast string to int?
On Thursday, February 02, 2012 11:11:28 Ali Çehreli wrote: > On 02/02/2012 11:00 AM, xancorreu wrote: > > Al 02/02/12 19:18, En/na bearophile ha escrit: > > > > Can I say "serialize the first, second and third arguments as Class > > Person"? > > > > I mean, if you define a class Person like: > > > > class Person { > > string name > > uint age > > dead bool > > } > > > > could you serialize the input from console, like > > Std.in.serialize(Person, args(0), args(1), args(2))? > > I haven't used it but there is Orange: > > https://github.com/jacob-carlborg/orange > > I think it will be included in Phobos. > > > You could do that "manually" checking each paramm, but it's a tedious > > task. > > If the input is exactly in the format that a library like Orange > expects, then it's easy. > > To me, constructing an object from user input is conceptually outside of > OO, because there is no object at that point yet. It makes sense to me > to read the input and then make an object from the input. > > Depending on the design, the input may be rejected by the function that > reads the input, by the constructor of the type, or by both. I'd be very surprised if Orange could help here (though I've never used it, so I don't know exactly what it can it). Normally, when you talk about serialization, you talk about serializing an object to another format (generally a binary format of some kind) and restoring it later, not creating an object. It's pretty much expected that if you're going to create an object from user input, you're going to have to do it yourself. That's perfectly normal. What makes the most sense for each application varies too much to really standardize it - especially when you consider error handling. What happens when not enough arguments were passed to the application? What if the values given can't be converted to the desired types? etc. If you have class Person { string name; uint age; bool dead; } I'd expect something like: int main(string[] args) { if(args.length != 4) { stderr.writeln("Not enough arguments."); return -1; } auto name = args[1]; uint age; try age = to!uint(args[2]); catch(ConvException ce) { stderr.writefln("[%s] is not a valid age.", args[2]); return -1; } bool dead; try dead = to!bool(args[3]); catch(ConvException ce) { stderr.writefln("[%s] is not a valid boolean value. It must be true or false.", args[3]); return -1; } auto person = Person(name, age, dead); //... return 0; } And whether that's the best way to handle it depends on what you're trying to do in terms of user input and error messages. How on earth is all of that going to be handled generically? It all depends on what the programmer is trying to do. Switching to use command-line switches and getopt would help some, but you still have to deal with the error messages yourself. Creating the Person is the easy part. - Jonathan M Davis
Re: Why I could not cast string to int?
On 02/02/2012 11:00 AM, xancorreu wrote: > Al 02/02/12 19:18, En/na bearophile ha escrit: > Can I say "serialize the first, second and third arguments as Class > Person"? > > I mean, if you define a class Person like: > > class Person { > string name > uint age > dead bool > } > > could you serialize the input from console, like > Std.in.serialize(Person, args(0), args(1), args(2))? I haven't used it but there is Orange: https://github.com/jacob-carlborg/orange I think it will be included in Phobos. > You could do that "manually" checking each paramm, but it's a tedious task. If the input is exactly in the format that a library like Orange expects, then it's easy. To me, constructing an object from user input is conceptually outside of OO, because there is no object at that point yet. It makes sense to me to read the input and then make an object from the input. Depending on the design, the input may be rejected by the function that reads the input, by the constructor of the type, or by both. > Thanks, > Xan. Ali
Re: Segment violation (was Re: Why I could not cast string to int?)
Al 02/02/12 19:30, En/na bearophile ha escrit: xancorreu: I get "segment violation" error with ./factorial 40 How can I resolve it? You are having a stack overflow. DMD currently doesn't print a good message because of this regression that is being worked on: http://d.puremagic.com/issues/show_bug.cgi?id=6088 On Windows with DMD you increase the stack like this: dmd -L/STACK:1 -run test2.d 40> result.txt If it goes in overflow still, increase the stack some more. But it will take a long time to compute the result even with the latest 2.058head with improved GC because the algorithm you have used to compute the factorial is very bad. I have rewritten your code like this: import std.stdio, std.bigint, std.conv, std.exception; BigInt recFactorial(in int n) { if (n == 0) return BigInt(1); else return BigInt(n) * recFactorial(n - 1); } void main(string[] args) { if (args.length != 2) { writeln("Factorial requires a number."); } else { try { writeln(recFactorial(to!int(args[1]))); } catch (ConvException e) { writeln("Error"); } } } Note the usage of ConvException, it's a very good practice to never use a generic "gotta catch them all" expression, because it leads to hiding other bugs in your code, and this is a source for troubles. Bye, bearophile Thank you very much for recode this. But you "only" put a "in" in recFactorial function argument. What this mean? **Why** this is more efficient than mine? For the other hand, how can increase the stack in linux? Thanks, Xan.
Re: Why I could not cast string to int?
Al 02/02/12 19:18, En/na bearophile ha escrit: Alex R. Petersen: (Sorry for my last blank answer.) Because D is a strongly typed language. Casting a string to an int doesn't make sense from a type system perspective. I think that D being strongly typed is not significant here. When you cast a string to char* you are casting a 2 words struct to a single pointer, when you cast a char* to long on a 32 bit system you are changing type and size, etc. The purpose of cast() is right to break the strongly typed nature of the D type system. So I think a better answer is that D designers have decided to give different purposes to to!X(y) and cast(X)x. The cast() is meant to be a light and very quick conversion, usually done at compile-time (unless it's a dynamic cast), to throw no exceptions, and generally unsafe. to!() is meant to be safer, to throw exceptions if the conversion fails, and it uses library code, so it's more flexible, and often performs some work at run-time too. Given such design a string->int conversion is better left to to!(). Bye, bearophile Okay, very useful answer! Can I say "serialize the first, second and third arguments as Class Person"? I mean, if you define a class Person like: class Person { string name uint age dead bool } could you serialize the input from console, like Std.in.serialize(Person, args(0), args(1), args(2))? You could do that "manually" checking each paramm, but it's a tedious task. Thanks, Xan.
Re: Why I could not cast string to int?
On Thursday, February 02, 2012 10:36:06 Ali Çehreli wrote: > Just to be complete: You mean it for fundamental types. Of course user > types' opCast operators may throw: > > import std.exception; > > class C > { > int opCast(T : int)() const > { > enforce(false, "Not good."); > return 42; > } > } > > void main() > { > auto c = new C; > auto i = cast(int)c; > } Very true. However, std.conv.to will use a user-defined opCast if there is one, and so it's generally better to use std.conv.to with user-defined opCasts than to cast explicitly. The risk of screwing it up is lower too, since then you don't have to worry about the built-in cast accidentally being used instead of your user-defined opCast if you screwed up - e.g. by declaring int opcast(T : int)() const { .. } Though in many cases, the compiler will still catch that for you (not all though). - Jonathan M Davis
i18n
Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) If not, any plannings? Thanks, Xan.
Re: Why I could not cast string to int?
On Thursday, February 02, 2012 13:18:17 bearophile wrote: > Alex R. Petersen: > > (Sorry for my last blank answer.) > > > Because D is a strongly typed language. Casting a string to an int > > doesn't make sense from a type system perspective. > > I think that D being strongly typed is not significant here. When you cast a > string to char* you are casting a 2 words struct to a single pointer, when > you cast a char* to long on a 32 bit system you are changing type and size, > etc. The purpose of cast() is right to break the strongly typed nature of > the D type system. > > So I think a better answer is that D designers have decided to give > different purposes to to!X(y) and cast(X)x. The cast() is meant to be a > light and very quick conversion, usually done at compile-time (unless it's > a dynamic cast), to throw no exceptions, and generally unsafe. to!() is > meant to be safer, to throw exceptions if the conversion fails, and it uses > library code, so it's more flexible, and often performs some work at > run-time too. Given such design a string->int conversion is better left to > to!(). Casts generally reintrepret what they're converting on some level (though not necessarily as exactly as C++'s reinterpret_cast does). The types involved are always similar and any converting that takes place is incredibly straightforward. They don't really convert in the sense of creating one type from another. It's closer to treating a type like another type than actually converting it. Strings are not at all similar to ints. One is an array. The other is a single integral value. So, it makes no sense to treat one like the other. std.conv.to, on the other hand, outright converts. It does what makes the most sense when trying to take a value of one type and create a value of another type from it. The two types may have absolutely nothing to do with each other. It's closer to constructing a value of one type from a value of another type than treating one like the other. So, as Bearophile says, the purposes of casting and std.conv.to are very different. - Jonathan M Davis
Re: Why I could not cast string to int?
On 02/02/2012 10:18 AM, bearophile wrote: > The cast() is meant to be a light and very quick conversion, > usually done at compile-time (unless it's a dynamic cast), I first read it as if you were saying that dynamic cast is the only one that is done at runtime. Actually many casts are done at runtime even for fundamental types. > to throw no exceptions, and generally unsafe. Just to be complete: You mean it for fundamental types. Of course user types' opCast operators may throw: import std.exception; class C { int opCast(T : int)() const { enforce(false, "Not good."); return 42; } } void main() { auto c = new C; auto i = cast(int)c; } > to!() is meant to be safer, to throw exceptions if the > conversion fails, and it uses library code, so it's more > flexible, and often performs some work at run-time too. Given > such design a string->int conversion is better left to to!(). Agreed. > > Bye, > bearophile Ali
Re: Segment violation (was Re: Why I could not cast string to int?)
xancorreu: > I get "segment violation" error with ./factorial 40 > How can I resolve it? You are having a stack overflow. DMD currently doesn't print a good message because of this regression that is being worked on: http://d.puremagic.com/issues/show_bug.cgi?id=6088 On Windows with DMD you increase the stack like this: dmd -L/STACK:1 -run test2.d 40 > result.txt If it goes in overflow still, increase the stack some more. But it will take a long time to compute the result even with the latest 2.058head with improved GC because the algorithm you have used to compute the factorial is very bad. I have rewritten your code like this: import std.stdio, std.bigint, std.conv, std.exception; BigInt recFactorial(in int n) { if (n == 0) return BigInt(1); else return BigInt(n) * recFactorial(n - 1); } void main(string[] args) { if (args.length != 2) { writeln("Factorial requires a number."); } else { try { writeln(recFactorial(to!int(args[1]))); } catch (ConvException e) { writeln("Error"); } } } Note the usage of ConvException, it's a very good practice to never use a generic "gotta catch them all" expression, because it leads to hiding other bugs in your code, and this is a source for troubles. Bye, bearophile
Re: Why I could not cast string to int?
Alex R. Petersen: (Sorry for my last blank answer.) > Because D is a strongly typed language. Casting a string to an int > doesn't make sense from a type system perspective. I think that D being strongly typed is not significant here. When you cast a string to char* you are casting a 2 words struct to a single pointer, when you cast a char* to long on a 32 bit system you are changing type and size, etc. The purpose of cast() is right to break the strongly typed nature of the D type system. So I think a better answer is that D designers have decided to give different purposes to to!X(y) and cast(X)x. The cast() is meant to be a light and very quick conversion, usually done at compile-time (unless it's a dynamic cast), to throw no exceptions, and generally unsafe. to!() is meant to be safer, to throw exceptions if the conversion fails, and it uses library code, so it's more flexible, and often performs some work at run-time too. Given such design a string->int conversion is better left to to!(). Bye, bearophile
Re: Why I could not cast string to int?
On 02-02-2012 17:26, xancorreu wrote: Why cast(int) does not work and I have to call another function? Thanks, Al 02/02/12 17:24, En/na Adam D. Ruppe ha escrit: On Thursday, 2 February 2012 at 16:21:39 UTC, xancorreu wrote: $ ./factorial 222 Factorial requires a number args[0] is the name of your program. (The first thing you typed on the command line.) Use args[1] to get that number. parse() where is the doc? http://www.d-programming-language.org/phobos/std_conv.html#parse to!int(args[1]) is probably what you want here though. Because D is a strongly typed language. Casting a string to an int doesn't make sense from a type system perspective. -- - Alex
Re: Why I could not cast string to int?
Alex Rønne Petersen Wrote: > On 02-02-2012 17:26, xancorreu wrote: > > Why cast(int) does not work and I have to call another function? > > > > Thanks, > > > > Al 02/02/12 17:24, En/na Adam D. Ruppe ha escrit: > >> On Thursday, 2 February 2012 at 16:21:39 UTC, xancorreu wrote: > >>> $ ./factorial 222 > >>> Factorial requires a number > >> > >> args[0] is the name of your program. > >> (The first thing you typed on the command > >> line.) > >> > >> Use args[1] to get that number. > >> > >>> parse() where is the doc? > >> > >> http://www.d-programming-language.org/phobos/std_conv.html#parse > >> > >> > >> to!int(args[1]) is probably what you want here though. > > > > Because D is a strongly typed language. Casting a string to an int > doesn't make sense from a type system perspective. > > -- > - Alex
Segment violation (was Re: Why I could not cast string to int?)
I get "segment violation" error with ./factorial 40 How can I resolve it? My code is: import std.stdio, std.bigint, std.string, std.conv, std.stream; BigInt recFactorial(int n) { if (n == 0) return BigInt(1); else return (BigInt(n) * recFactorial(n - 1)); } void main(string[] args) { if (args.length != 2) writeln("Factorial requires a number"); else try { writeln(recFactorial(std.conv.to!int(args[1]))); } catch { writeln("Error"); } } Thanks a lot,
Re: Why I could not cast string to int?
Why cast(int) does not work and I have to call another function? Thanks, Al 02/02/12 17:24, En/na Adam D. Ruppe ha escrit: On Thursday, 2 February 2012 at 16:21:39 UTC, xancorreu wrote: $ ./factorial 222 Factorial requires a number args[0] is the name of your program. (The first thing you typed on the command line.) Use args[1] to get that number. parse() where is the doc? http://www.d-programming-language.org/phobos/std_conv.html#parse to!int(args[1]) is probably what you want here though.
Re: Why I could not cast string to int?
Al 02/02/12 16:58, En/na David Nadlinger ha escrit: On 2/2/12 1:35 PM, xancorreu wrote: In this code, how can I cast the args[0] string to int for computing factorial(args[0])? std.conv.to!int(…) or parse(). Sorry, if condition was wrong. conv.to!int is perfect! Thanks, Hope this helps, David
Re: Why I could not cast string to int?
On Thursday, 2 February 2012 at 16:21:39 UTC, xancorreu wrote: $ ./factorial 222 Factorial requires a number args[0] is the name of your program. (The first thing you typed on the command line.) Use args[1] to get that number. parse() where is the doc? http://www.d-programming-language.org/phobos/std_conv.html#parse to!int(args[1]) is probably what you want here though.
Re: Why I could not cast string to int?
Al 02/02/12 16:58, En/na David Nadlinger ha escrit: On 2/2/12 1:35 PM, xancorreu wrote: In this code, how can I cast the args[0] string to int for computing factorial(args[0])? std.conv.to!int(…) or parse(). to!int gives me this error: $ ./factorial 222 Factorial requires a number parse() where is the doc? Thanks in advance, Xan. Hope this helps, David
Re: Why I could not cast string to int?
Use to!int(args[1]) > I receive: > $ gdmd-4.6 factorial.d > factorial.d: In function ‘main’: > factorial.d:15:0: error: cannot cast expression of type string to int > > > Thanks in advance, > Xan.
Re: Why I could not cast string to int?
On 2/2/12 1:35 PM, xancorreu wrote: In this code, how can I cast the args[0] string to int for computing factorial(args[0])? std.conv.to!int(…) or parse(). Hope this helps, David
Why I could not cast string to int?
Hi, In this code, how can I cast the args[0] string to int for computing factorial(args[0])? import std.stdio, std.bigint, std.string, std.conv, std.stream; BigInt recFactorial(int n) { if (n == 0) return BigInt(1); else return (BigInt(n) * recFactorial(n - 1)); } void main(string[] args) { if (args.length == 2) writeln("Factorial requires a number"); else try { writeln(recFactorial(cast(int) args[1])); } catch { writeln("Error"); } } I receive: $ gdmd-4.6 factorial.d factorial.d: In function ‘main’: factorial.d:15:0: error: cannot cast expression of type string to int Thanks in advance, Xan.
Re: sameness
On 01/20/2012 01:18 PM, sclytrack wrote: --- letters are different yet the same immutable(char) [] letter1; const(char) [] letter2; char [] letter3; void proc1( const(char) [] letter) {} --- letters are different struct Container(T) { T letter; } Container!(const(char)) letter1; Container!(immutable(char)) letter2 Container!(char) letter3; void proc2(Container!(const(char)) letter) {} --- This means we can't create a Stride that would behave like a built in type. int stride a = new int stride(2,100); const int stride b = a; writeln(a.step); a[10]++; inout(int) hello(inout(int) stride a, inout(int) stride b) inout { } I've also noticed something. There is a lot of casting in the inout. 5 degrees Celsius. These modern computers barely heat up the room.