Re: [std.database]
On 2011-10-11 23:09, Johann MacDonagh wrote: On 10/11/2011 4:07 AM, Jacob Carlborg wrote: I think that the use of opDispatch and selecting with a struct should be available at the higher level interfaces and not in the low level interface. What do you mean by this? Do you mean instead of having the opDispatch in the Connection class, we'd have it in a separate struct / template / other magic? This would allow us to utilize this method for other sources of data, such as XML. Something like that. Take advantage of opDispatch in a more ORM like interface. Which also hides the connection and executing of raw SQL. On the other hand though, this doesn't add a whole lot. Let's say we had this code: auto rows = db.execute("SELECT score, a.user FROM users a JOIN scores b on a.user = b.user"); foreach (row; rows) { writeln(to!int(row["score"])); } I think that the above code would sit in a middle layer between the lower level of the database driver and a higher level of an ORM like interface. See my reply to one of Andrei's posts. -- /Jacob Carlborg
Re: [std.database]
On Mon, 10 Oct 2011 22:09:49 +0200, Piotr Szturmaj wrote: > Steve Teale wrote: >> I've just been looking at the documentation for the PostgreSQL C api. >> Wow! >> >> It is so different from MySQL, and so clean. No out parameters from >> queries. That one is not going to be a problem. >> >> Steve > > PostgreSQL's C lib is not needed if we handle postgres protocol directly > (already done). Is that something that the user is going to be comfortable with if she has to step out of the bounds of our implementation. I would feel better using Posgres' excellent api documentation.
Re: [std.database]
>> >> I might be narrow-minded, but I thought we're still looking at writing >> and executing good old SQL code. >> >> Andrei >> >> > We should always allow the user to get down to the nitty-gritty and > write good ol' SQL statements and execute them. However, writing all > that plumbing code gets old very quickly, so if we can provide some > clean and simple frameworks on top of that, users would appreciate it. I'm mostly with Andei. I'm all for sophisticated techniques, but what the user has to do should not look like a primer for them. Also if the user has to change down a cog the lower-level interfaces should not look like they're written in another language. >From my experiments with MySQL I believe we can provide clean and simple frameworks. But, you get what you pay for - simple interfaces will be suitable for simple cases. Steve
Re: [std.database]
On Tue, 11 Oct 2011 09:29:57 -0400, Andrei Alexandrescu wrote: On 10/10/11 11:02 PM, Robert Jacques wrote: On Mon, 10 Oct 2011 11:09:34 -0400, Andrei Alexandrescu wrote: On 10/10/11 7:01 AM, Steve Teale wrote: [snip] That's a bug in std.variant. Large structs should be supported automatically by using an indirection and dynamic allocation. For what it's worth, my improved Variant proposal, does do that. (i.e. it fixes the bug) Is it ready for review? Andrei Yes. However, I'm currently writing my PhD thesis so my bandwidth is limited.
Re: Matrix-type-friendly syntax and more
Robert Jacques: >[... several things] > Seventh, Matlab, NumPy, Octave, BLAS, etc. all support striding. OK, a nice striding syntax for user defined types will be a good thing to have in D2. I have suggested the x..y:y syntax. Is this usable? Is this going to cause problems? Bye, bearophile
Re: Matrix-type-friendly syntax and more
On Tue, 11 Oct 2011 11:48:54 -0400, Gor Gyolchanyan wrote: I don't think strides are necessary. You can always opApply your image in a certain way. Define a private struct, which has an opApply, which iterates over every third channel of each pixel. lazy ranges are generally better, then arrays, because with them, you can avoid copying anything altogether. First, slicing / striding doesn't imply copying. Second, striding allows you to mutate the original data, which many lazy ranges do not. Third, there is a heavy amount of over-head to opApply, as its delegate based. Forth, declaring a custom type is way too much programmer boilerplate, even using something like Tuple!(ubyte,ubyte,ubyte,ubyte) is overly verbose. Fifth, my example was about dynamically supporting multiple data formats using the same code, something not possible with a custom struct. Sixth, we are talking about multi-dimensional arrays, not D's built-in arrays; lazy ranges don't exactly apply. Although, on the subject of Multi-dimensional ranges/iteration, has anyone else taken a look at the FLAME project? (http://z.cs.utexas.edu/wiki/flame.wiki) Seventh, Matlab, NumPy, Octave, BLAS, etc. all support striding.
Re: [std.database]
On 10/11/11 7:43 PM, Johann MacDonagh wrote: We should always allow the user to get down to the nitty-gritty and write good ol' SQL statements and execute them. However, writing all that plumbing code gets old very quickly, so if we can provide some clean and simple frameworks on top of that, users would appreciate it. The way I see it, I should either learn SQL plus some alternate syntax for it, or SQL alone. Andrei
Re: std.database design suggestion
Am 10.10.2011 12:04, schrieb bls: -- Sorry for posting on D.announce -- Hi, what do you people think about using the GoF Factory (design) pattern ? F.I. abstract class Database { //common database stuff public abstract void connect(string user, string pw); // execSql(); prepare() etc... } abstract class DatabaseFactory { public abstract Database GetDatabase(); } class PostgreSQL:Database { // common public override void connect(string user, string pw) { } //PostgreSQL specific public void funkyPGstuff() {} } class PostreSQLFactory:DatabaseFactory { public override Database GetDatabase() { return new PostgreSQL(); } } class MySQL:Database { // common public override void connect(string user, string pw) { } //MySQL specific public void funkyMySQLstuff() {} } class MySQLFactory:DatabaseFactory { public override Database GetDatabase() { return new MySQL(); } } I think this would make sense and JDBC does something similar, if I recall correctly. Cheers, - Daniel
Re: [std.database]
On 10/11/2011 5:46 PM, Adam Ruppe wrote: Andrei Alexandrescu wrote: The database engine should be codified in the connection string, not in the type name. Why? If it's in the type, you can trivially specialize for different engines and get static checking for functions not supported across them all, or runtime checking if you prefer. You can also change the constructors to make it clear what is being created. Agreed. In addition, if DbConnection handled all connections based on the connection string (of course, we're assuming connection strings are all unique here), then DbConnection would have to be modified to support a new driver. DbConnection should have the lowest common denominator implementation / abstract routines, and the specialized Connection classes would work from that. That's how ADO.net works at least.
Re: [std.database]
On 10/11/2011 5:31 PM, Andrei Alexandrescu wrote: On 10/11/11 3:05 PM, Jacob Carlborg wrote: If we're talking use cases and high level interfaces I would go with something like: [snip] I recommend that everyone take a good look at ActiveRecord in Ruby on Rails: http://guides.rubyonrails.org/active_record_querying.html http://guides.rubyonrails.org/association_basics.html http://guides.rubyonrails.org/active_record_validations_callbacks.html I confess the example you gave looks very foreign to me. From consulting http://guides.rubyonrails.org/active_record_querying.html, I see Ruby's active records esentially recode relational algebra in Ruby (as for the constructs the equivalent SQL is shown). For a variety of reasons, this would be tenuous in D. One simple reason is that e.g. lambdas don't offer access to textual representation, which would be necessary to translate lambda-based conditions into SQL text. I might be narrow-minded, but I thought we're still looking at writing and executing good old SQL code. Andrei We should always allow the user to get down to the nitty-gritty and write good ol' SQL statements and execute them. However, writing all that plumbing code gets old very quickly, so if we can provide some clean and simple frameworks on top of that, users would appreciate it.
Re: Should unreachable code be considered an error?
On 02/10/2011 22:41, Walter Bright wrote: On 10/2/2011 2:18 PM, Stewart Gordon wrote: Simply because we can't rely on every compiler to perform even the most basic cases of DCE? Consider: if (a) { ... code ... } Sometimes, when debugging, I'll do: if (0 && a) { ... code ... } I was talking about cases of DCE that are even more basic than this, such as: void qwert() { return; yuiop(); } void asdfg() { if (hjkl) { return zxcvb; } else { return nm; } qaz(); } These are exactly what I mean by no arrow leading to a given statement. In your examples, OTOH, the arrow exists - it will just never be followed. Stewart.
Re: Hooray for DustMite
On Mon, 10 Oct 2011 09:26:55 +0300, Andrew Wiley wrote: Thanks! I'm glad so many people are finding DustMite useful :) I can't help but wonder if it can be helpful to people outside the D community. Support for other languages is pretty easy to add. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: Static arrays, typeof and IFTI?
On Monday, October 10, 2011 22:55 Norbert Nemec wrote: > Even worse for template arguments. My first idea (inspired by C++, also > suggested by kennytm) > > template(T,int N) myfunc(T[N] arg) > > does not work in D and I could not find any alternative way to allow > writing > > myfunc([1,2,3,4]) It does if you pass it an actual static array. For instance, std.bitmanip.bigEndianToNative has a similar declaration. The problem with your example stems from the fact that the literal is a dynamic array, and the compiler fails to take the implicit conversion into account when instantiating the template. So, for instance myfunc(cast(int[4])[1, 2, 3, 4]); works. Obviously, that's not really what you're looking for, but the templated function is just fine. It's just that template instantiation is very exact and doesn't do much (if anything) in the way of conversions. - Jonathan M Davis
Re: Static arrays, typeof and IFTI?
Don Wrote: > On 11.10.2011 18:54, bearophile wrote: > > Andrei Alexandrescu: > > > >> I was more enthused about that, but later I realized there are very few > >> situations in which one reasonably has a fixed-size array that is large > >> enough to make counting inadequate and is also updated often enough to > >> make the feature worthwhile. It's one of those features that are nice to > >> have but are not really missed in real code. > > > > I am not going to appreciate a language/compiler that accepts and compiles > > this program silently. This trap has caused a bug in my code time ago: > > > > int[3] a = [1, 2]; > > void main() {} > > I've hit that bug many, many times. But... > > > The usage of [$] in that case avoids that kind of bug... > > How? The code above would still compile. What is the "correct" version of the code? The array [1,2] of length 2 or a sequence literal [1,2,x] (with x = some not yet specified) with length 3? The compiler can't know what the right code is. If you write [$] on the left you are saying to the compiler that the correct thing is the sequence literal you have written on the right of the equal sign. If you don't use [$] it means you want exactly N items (so if the sequence literal on the right contains less than N then there is a bug). And finally some people have even said that if you put a [, ...] at the end of the sequence literal on the right of the equal sign then the specified N number of items on the left is the correct information, and the not specified items in the sequence literal on the right need to be filled with .init. > Would be much better to just > ban assigning an array literal to an static array of different length. For me this is an acceptable solution, it's safe, and it's the simplest one. This was present in the the patch in Bugzilla (but because of my silly poking nose it was later removed). But it sometimes forces you to count items manually (and in some very uncommon cases forces you to add leading zeros manually, but this is not a problem). Bye, bearophile
Re: Static arrays, typeof and IFTI?
David Gileadi: > It would be nice if this were coupled with an earlier suggestion: > > // large buffer starting with 1, 2 and the remainder zeros > int[1000] a = [1, 2, 0..]; We discussed this a bit, in past. That syntax gives problems. This is better: > int[1000] a = [1, 2, ...]; This is nice, but as we said in past, the need for this code is not that common. I've never needed this so far (while as example I'd enjoy to use an array comprehension syntax about every 20 lines of D code, or tuple syntax about as often). Bye, bearophile
Re: [std.database]
Andrei Alexandrescu wrote: > The database engine should be codified in the connection string, > not in the type name. Why? If it's in the type, you can trivially specialize for different engines and get static checking for functions not supported across them all, or runtime checking if you prefer. You can also change the constructors to make it clear what is being created.
Re: Matrix-type-friendly syntax and more
On 11.10.2011 17:48, Gor Gyolchanyan wrote: > I don't think strides are necessary. You can always opApply your image > in a certain way. Define a private struct, which has an opApply, which > iterates over every third channel of each pixel. > lazy ranges are generally better, then arrays, because with them, you > can avoid copying anything altogether. Actually, a strided slice to a multidimensional array can easily be implemented as a view to the original data without any copy action, just like any builtin array slice is a view to the data. Independent of that: of course strides are not "necessary", but they are an extremely convenient syntax for expressing numerical array operations.
Re: [std.database]
On 10/11/11 4:00 PM, Johann MacDonagh wrote: On 10/11/2011 1:57 AM, Piotr Szturmaj wrote: Johann MacDonagh wrote: Maybe "Database" should be an abstract class rather than an interface? That's how ADO.net does it: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx Why "Database" instead of PGConnection, MySqlConnection, SQLiteConnection, etc. ? And of course base SqlConnection. No, I agree. The base type should be DbConnection (I dunno, SqlConnection is a little too specific, I like DbConnection better), extended by PGConnection, MySqlConnection, SqliteConnection, etc... The database engine should be codified in the connection string, not in the type name. Andrei
Re: [std.database]
On 10/11/11 3:05 PM, Jacob Carlborg wrote: If we're talking use cases and high level interfaces I would go with something like: [snip] I recommend that everyone take a good look at ActiveRecord in Ruby on Rails: http://guides.rubyonrails.org/active_record_querying.html http://guides.rubyonrails.org/association_basics.html http://guides.rubyonrails.org/active_record_validations_callbacks.html I confess the example you gave looks very foreign to me. From consulting http://guides.rubyonrails.org/active_record_querying.html, I see Ruby's active records esentially recode relational algebra in Ruby (as for the constructs the equivalent SQL is shown). For a variety of reasons, this would be tenuous in D. One simple reason is that e.g. lambdas don't offer access to textual representation, which would be necessary to translate lambda-based conditions into SQL text. I might be narrow-minded, but I thought we're still looking at writing and executing good old SQL code. Andrei
Re: Matrix-type-friendly syntax and more
On 11.10.2011 09:05, Don wrote: > On 10.10.2011 20:03, Norbert Nemec wrote: >> >> Inefficient?! For multidimensional arrays, all but one dimension have >> non-trivial, runtime-dependent strides anyway. > > The problem is with built-in arrays. Sure. For one-dimensional arrays, the overhead would be significant and the use would be limited to exotic cases. >> Anyway, the expressiveness gained by strides is significant and the >> effort to allow it in the language is minimal. > > That's true, IF you are happy to have it as a feature which can only be > used in user-defined types. If you want it apply to built-in arrays as > well, the effort is immense. Indeed, I am interested in this feature purely for defining multidimensional arrays for use in numerics.
Re: Static arrays, typeof and IFTI?
On 11.10.2011 15:35, Andrei Alexandrescu wrote: > On 10/11/11 2:56 AM, bearophile wrote: >> Since years some people (among them there is me too) are asking for >> this syntax: >> >> int arr[$] = [1,2,3,4]; >> >> Vote for it here (an enhancement request from 2006!): >> http://d.puremagic.com/issues/show_bug.cgi?id=481 > > I was more enthused about that, but later I realized there are very few > situations in which one reasonably has a fixed-size array that is large > enough to make counting inadequate and is also updated often enough to > make the feature worthwhile. It's one of those features that are nice to > have but are not really missed in real code. How about function templates? You can start overloading like void f(int[1] x); void f(int[2] x); void f(int[3] x); but there is no way to do it via a single template. The only way to do it would be explicit instantiation void f(int N)(int[N] x); to be called as f!(3)([1,2,3]); Of course, this can always be done, but to me it seems ugly enough to think about a solution.
Re: [std.database]
On 10/11/2011 4:07 AM, Jacob Carlborg wrote: I think that the use of opDispatch and selecting with a struct should be available at the higher level interfaces and not in the low level interface. What do you mean by this? Do you mean instead of having the opDispatch in the Connection class, we'd have it in a separate struct / template / other magic? This would allow us to utilize this method for other sources of data, such as XML. On the other hand though, this doesn't add a whole lot. Let's say we had this code: auto rows = db.execute("SELECT score, a.user FROM users a JOIN scores b on a.user = b.user"); foreach (row; rows) { writeln(to!int(row["score"])); } We could also add in a generic range operation that converts a range of Variant[string] (a row) to a struct specified by the user. The code would become: auto rows = extractStructs!(MyStruct, db.execute("SELECT score, a.user FROM users a JOIN scores b on a.user = b.user")); foreach (row; rows) { writeln(row.score); } I suppose I'm just remembering how much plumbing code had to be done when accessing databases in C#. It sounds like doing this from D will be much easier, even without my silly "LINQ" concept.
Re: Static arrays, typeof and IFTI?
On 10/11/11 1:46 PM, simendsjo wrote: // It's important that a has a length of 3, so I specify it int[3] a = [1, 2] Error: Not enough values for a. Expected 3, got 2 // I don't care what length a has as long as it has a static length int[$] a = [1, 2]; It would be nice if this were coupled with an earlier suggestion: // large buffer starting with 1, 2 and the remainder zeros int[1000] a = [1, 2, 0..];
Re: [std.database]
On 10/11/2011 1:57 AM, Piotr Szturmaj wrote: Johann MacDonagh wrote: Maybe "Database" should be an abstract class rather than an interface? That's how ADO.net does it: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx Why "Database" instead of PGConnection, MySqlConnection, SQLiteConnection, etc. ? And of course base SqlConnection. No, I agree. The base type should be DbConnection (I dunno, SqlConnection is a little too specific, I like DbConnection better), extended by PGConnection, MySqlConnection, SqliteConnection, etc...
Re: Static arrays, typeof and IFTI?
On 11.10.2011 22:31, Don wrote: On 11.10.2011 18:54, bearophile wrote: Andrei Alexandrescu: I was more enthused about that, but later I realized there are very few situations in which one reasonably has a fixed-size array that is large enough to make counting inadequate and is also updated often enough to make the feature worthwhile. It's one of those features that are nice to have but are not really missed in real code. I am not going to appreciate a language/compiler that accepts and compiles this program silently. This trap has caused a bug in my code time ago: int[3] a = [1, 2]; void main() {} I've hit that bug many, many times. But... The usage of [$] in that case avoids that kind of bug... How? The code above would still compile. Would be much better to just ban assigning an array literal to an static array of different length. // It's important that a has a length of 3, so I specify it int[3] a = [1, 2] Error: Not enough values for a. Expected 3, got 2 // I don't care what length a has as long as it has a static length int[$] a = [1, 2];
Re: Static arrays, typeof and IFTI?
On 11.10.2011 18:54, bearophile wrote: Andrei Alexandrescu: I was more enthused about that, but later I realized there are very few situations in which one reasonably has a fixed-size array that is large enough to make counting inadequate and is also updated often enough to make the feature worthwhile. It's one of those features that are nice to have but are not really missed in real code. I am not going to appreciate a language/compiler that accepts and compiles this program silently. This trap has caused a bug in my code time ago: int[3] a = [1, 2]; void main() {} I've hit that bug many, many times. But... The usage of [$] in that case avoids that kind of bug... How? The code above would still compile. Would be much better to just ban assigning an array literal to an static array of different length.
Re: [std.database]
On 2011-10-11 19:40, Andrei Alexandrescu wrote: This makes sense from the perspective of a database implementor who needs to provide the appropriate interfaces, but I think a better angle would be to focus on use cases and work the API backwards from there. Here's what I think should be a complete program: import std.sql, std.stdio; void main() { auto db = connect(" engine = mysql; user = john; password = doe; port = 6900; "); auto rows = db.execute("SELECT score, a.user FROM users a JOIN scores b on a.user = b.user"); foreach (row; rows) { writeln("%10s\t%s", row[0], row[1]); // or // writeln("%10s\t%s", row["score"], row["user"]); } } This should cleanly close everything upon exiting from main, provide proper error reporting if anything bad happens (and a lot could go wrong: malformed conn string, missing driver, wrong username/password, connection errors, malformed query, wrong column name...). Using the interfaces you propose directly would allow one to implement the same program, but with significant extra chaff. That's why suggest we focus on user-level APIs first because in many ways those are the most important thing. Then we will distill the proper interfaces. So the question is - what should a typical database task look like? That includes prepared statements, binding to tuples and structs, and a lot more. Andrei If we're talking use cases and high level interfaces I would go with something like: class Post : Model { mixin hasMany!("comments"); } class Comment : Model { mixin belongsTo!("post"); } The above mixins are very ugly. This would be perfect for user definable annotations/attributes void main () { Connection connection = new MySqlConnection("localhost", "john", "doe", "6900"); // or using field syntax connection.host = "localhost"; connection.username = "john"; connection.password = "doe"; connection.port = "6900"; auto posts = Post.all; // lazily get all rows from the table "posts" posts = posts.where("title = ?", "foobar"); // add where condition // or if this is possible, using new-style lambda syntax posts = posts.where(post => post.title == "foobar"); foreach (post ; posts) // execute SQL here { // get the title and content via opDispatch writeln("title: %s\n\n%s", post.title, post.content); writeln("Comments:\n"); foreach (comment ; post.comments) // lazily loaded comments writeln(comments.content); } auto post = new Post; post.title = "foobar"; // this is not currently possible with opDispatch post.content = "content of post"; // create a new row in the "posts" table post.save; } I haven't figured out yet how to connect a connection to the models. Perhaps assigning a connection object to the base class "Model": // using field syntax Model.connection.host = "localhost"; Model.connection.username = "john"; Model.connection.password = "doe"; Model.connection.port = "6900"; // or by assigning a new connection object Model.connection = new MySqlConnection("localhost", "john", "doe", "6900"); Anyway, this is what I think the highest level of the interfaces could look like. I recommend that everyone take a good look at ActiveRecord in Ruby on Rails: http://guides.rubyonrails.org/active_record_querying.html http://guides.rubyonrails.org/association_basics.html http://guides.rubyonrails.org/active_record_validations_callbacks.html -- /Jacob Carlborg
Re: Formal Review of std.regex (FReD)
I have 2 thoughts. 1) Minor doc typo: Long form for hex notation should be \U00YY. 2) Unicode set syntax If you're going to provide unicode set support, why not use ICU syntax rather than invent another one? Jerry
Re: religious programming
Right. But I'm one, they're many. I don't have enough manpower to do that, while I need those people to write libraries in D for me to use. That's the problem. On Tue, Oct 11, 2011 at 11:35 PM, Peter Alexander wrote: > On 11/10/11 10:57 AM, Gor Gyolchanyan wrote: >> >> Can anyone help me out in this quest of enlightening people? > > You can only enlighten people if you are enlightened. > > I'm not saying that you're not, but how can you know? Do you really know > everything there is to know about computer programming, and all the issues > surrounding it? I know I don't. > > In my opinion, if you want to show people the merits of D, then show them! > Write lots of amazing software in D and show it to the world via github, > reddit, etc. You're not going to convince many people by arguing with them, > but you will convince them through example. >
Re: religious programming
On 11/10/11 10:57 AM, Gor Gyolchanyan wrote: Can anyone help me out in this quest of enlightening people? You can only enlighten people if you are enlightened. I'm not saying that you're not, but how can you know? Do you really know everything there is to know about computer programming, and all the issues surrounding it? I know I don't. In my opinion, if you want to show people the merits of D, then show them! Write lots of amazing software in D and show it to the world via github, reddit, etc. You're not going to convince many people by arguing with them, but you will convince them through example.
Re: religious programming
Paulo Pinto Wrote: > True, but you will see seldom things like LINQ or generators being used > in corporate projects with offshoring, unless it is somehow required by > the APIs being used. > > Corporate world likes to think of programmers as replaceable items, and > that can only be done with simple programming concepts. Inheritance and overloading can get really tough, while one can use linq without reading a line about it. an example: class DBException: Exception{} void Handle(Exception e){ log("Exception handled"); } void Handle(DBException e){ log("DBException handled"); } Handle(null); // which method is called? Can you expect this level of expertise from an average codemonkey? BTW we found this pattern in our code.
Re: religious programming
Come to think of it, it's exactly the same situation here. Some people still use and love C. One of the most famous programmers is a C guru and he used his expertise in C to write the even more famous OS kernel., which sits in the heart of the vast majority of operating systems today. By making D and DMD open-source and community-driven you ensured it's usability-oriented evolution. I can't thank you enough for that. :-) When I finally finish my first project with my brother and start selling it, I'll quit my job and get self-employed, which will allow me to direct more effort in developing D. After all, D is the source of my future profit. I gotta invest in my own profit. On Tue, Oct 11, 2011 at 9:55 PM, Walter Bright wrote: > On 10/11/2011 2:57 AM, Gor Gyolchanyan wrote: >> >> Can anyone help me out in this quest of enlightening people? > > There was the same thing with C programmers when C++ was new. People would > insist that they could do OOP in C, and yes, they could. I've seen it. It > works. > > It is awful, though. > > People who were willing to learn new things moved on to C++. The C community > didn't go away, but it did become a community of very conservative > programmers who resisted anything new. Look at the evolution of the C > standard since then - change is practically nonexistent. All the people that > wanted change moved to other languages. > > So I wouldn't worry about it. We need to concentrate on making D the best we > can. To help spread the word, the best way is to write articles about D. >
Re: religious programming
Well, to be honest, I'm just as cynic as you :-) I agree with everything you said. :-) On Tue, Oct 11, 2011 at 9:19 PM, Paulo Pinto wrote: > There is some truth in what you say Gor, but I have seen it going > in a complete direction all the time. > > I lost count the amount of Corporate projects I had contact with, which > were developed multi-site across the globe. With sites being changed in a > few months, just because some figures in the management Excel did not > look good. > > True, most good developers eventually go away. The few ones that stay > around, do so due to other factors besides "coding fun". > > I have seen too many Corporate projects where the teams literaly do > body shopping. You don't get the right people for the project, but the > ones which happen to be somehow available. > > With time I have become a bit cynic and now consider that C++, D, Scala > and so on, are languages for people with brain, while Java, VB.Net and > others are offshoring/outsourcing languages. > > > Am 11.10.2011 17:58, schrieb Gor Gyolchanyan: >> >> The paradox of good developers is: truly irreplaceable developer is >> one, that can be easily replaced. >> The better the developer works, the easier it is to get rid of him. >> But the one you'll replace him with won't work as good and will make >> code, which is expensive to understand for newbies. >> So you won't wanna replace him, which makes him irreplaceable. >> >> On Tue, Oct 11, 2011 at 7:40 PM, Paulo Pinto wrote: >>> >>> Am 11.10.2011 13:43, schrieb Kagamin: Gor Gyolchanyan Wrote: > But this is not gonna happen with such religious attitude to > programming. > They say built-in arrays are useless, because there's always > std::vector and std::list. > They say, functional programming and lambdas are useless, because you > can make functors and base classes for them. C# is a corporate language and it has no problem with built-in arrays, strings, lambdas and delegates, and constantly introduces new features like linq, generators, covariant templates. >>> >>> True, but you will see seldom things like LINQ or generators being used >>> in >>> corporate projects with offshoring, unless it is somehow required by >>> the APIs being used. >>> >>> Corporate world likes to think of programmers as replaceable items, and >>> that >>> can only be done with simple programming concepts. >>> > >
Re: religious programming
"Gor Gyolchanyan" wrote in message news:mailman.37.1318327068.24802.digitalmar...@puremagic.com... >I can't keep it in any more, I have to share. > > I've seen lots of corporate C++ code and coding guidelines and I came > to the conclusion, that they're all bogus. > The vast majority of code, being written in commercial projects use a > very limited subset of the language they use. > The code I work with currently is a purely object-oriented C++ code. > I used to like object-oriented programming until I started working > with that code. > Corporate code is very religious. They use a few specialized > techniques for everything. > They use object-oriented programming when functional programming is > the technique of choice. > They use object-oriented programming when generic programming is the > technique of choice. > The code is unimaginably bloated, flooded with thousands of tiny > redundant classes, each of which do a primitive task, which doesn't > need to be a class at all. > I've discussed D with my colleagues lately and the vast multi-paradigm > and built-in featured of D were discarded with a religious "There's a > class already written for that.". > Why do I keep saying "religious"? Because they are convinced, that > this is the way to go and do not accept any logical arguments. > Why do I talk about this at all? Because corporate code is the one we > need to become D. > But this is not gonna happen with such religious attitude to programming. > They say built-in arrays are useless, because there's always > std::vector and std::list. > They say, functional programming and lambdas are useless, because you > can make functors and base classes for them. > They say garbage collection is useless, because there's always > std::shared_ptr. > Well, yes. You do have all that. But look what the code looks like and > how fast it runs! > > It's amazing how stupid and ignorant can corporate developers be > sometimes and how smart and considerate open-source developers can be. > I don't know how to cure the people's minds from this religious > plague, that poisons the software development industry. > Hear, hear!
Re: religious programming
On 10/11/2011 2:57 AM, Gor Gyolchanyan wrote: Can anyone help me out in this quest of enlightening people? There was the same thing with C programmers when C++ was new. People would insist that they could do OOP in C, and yes, they could. I've seen it. It works. It is awful, though. People who were willing to learn new things moved on to C++. The C community didn't go away, but it did become a community of very conservative programmers who resisted anything new. Look at the evolution of the C standard since then - change is practically nonexistent. All the people that wanted change moved to other languages. So I wouldn't worry about it. We need to concentrate on making D the best we can. To help spread the word, the best way is to write articles about D.
Re: [std.database]
On Tue, Oct 11, 2011 at 12:40:52PM -0500, Andrei Alexandrescu wrote: > auto db = connect(" > engine = mysql; > user = john; > password = doe; > port = 6900; > "); Why is that a string? I'd just use different constructors for different engines, and let them work however they work for the target. Here's what a simple program looks like with my database code: import arsd.mysql; void main() { auto db = new MySql("localhost", "user", "password", "database"); scope(exit) delete db; foreach(line; db.query("do whatever")) { writeln(line[0], line[1]); } } OR import arsd.postgres; void main() { auto db = new PostgreSql("dbname = test"); scope(exit) delete db; foreach(line; db.query("do whatever")) { writeln(line[0], line[1]); } } OR import arsd.sqlite; void main() { auto db = new Sqlite("my-database.db"); scope(exit) delete db; foreach(line; db.query("do whatever")) { writeln(line[0], line[1]); } } The biggest downside might be that the databases are classes, so you either scope them or garbage collect them.. but that doesn't really bother me.
Re: [std.database]
On 10/10/11 9:07 AM, Steve Teale wrote: Here's a sketch of an interface. This is based on my experiments with MySQL, and as such it is probably mid-level, and not a top level covers- all interface. Hopefully it will create a number of discussion points. // Can interfaces include template functions??? interface SQLDBConnection { @property Handle handle(); Handle connect(string host, string user, string password, string database = null); T getProperty(T)(string name); T getProperty(T)(int id); void setProperty(T)(T property, string name); void setProperty(T)(T property, int id); Handle disconnect(); } [snip] This makes sense from the perspective of a database implementor who needs to provide the appropriate interfaces, but I think a better angle would be to focus on use cases and work the API backwards from there. Here's what I think should be a complete program: import std.sql, std.stdio; void main() { auto db = connect(" engine = mysql; user = john; password = doe; port = 6900; "); auto rows = db.execute("SELECT score, a.user FROM users a JOIN scores b on a.user = b.user"); foreach (row; rows) { writeln("%10s\t%s", row[0], row[1]); // or // writeln("%10s\t%s", row["score"], row["user"]); } } This should cleanly close everything upon exiting from main, provide proper error reporting if anything bad happens (and a lot could go wrong: malformed conn string, missing driver, wrong username/password, connection errors, malformed query, wrong column name...). Using the interfaces you propose directly would allow one to implement the same program, but with significant extra chaff. That's why suggest we focus on user-level APIs first because in many ways those are the most important thing. Then we will distill the proper interfaces. So the question is - what should a typical database task look like? That includes prepared statements, binding to tuples and structs, and a lot more. Andrei
Re: questions: remove from SList
"Steven Schveighoffer" wrote: > Yes, I'd agree either remove's implementation or its constraint > specification are buggy. It should not specify that it needs a forward > range and then use bi-directional range primitives. > I think remove's constraint is fine. With a SList you don't really want to remove the current node, but the 'next' node. SList should provide the O(1) removeNext and insertNext functions (c.f. C++11's std::forward_list).
Re: religious programming
There is some truth in what you say Gor, but I have seen it going in a complete direction all the time. I lost count the amount of Corporate projects I had contact with, which were developed multi-site across the globe. With sites being changed in a few months, just because some figures in the management Excel did not look good. True, most good developers eventually go away. The few ones that stay around, do so due to other factors besides "coding fun". I have seen too many Corporate projects where the teams literaly do body shopping. You don't get the right people for the project, but the ones which happen to be somehow available. With time I have become a bit cynic and now consider that C++, D, Scala and so on, are languages for people with brain, while Java, VB.Net and others are offshoring/outsourcing languages. Am 11.10.2011 17:58, schrieb Gor Gyolchanyan: The paradox of good developers is: truly irreplaceable developer is one, that can be easily replaced. The better the developer works, the easier it is to get rid of him. But the one you'll replace him with won't work as good and will make code, which is expensive to understand for newbies. So you won't wanna replace him, which makes him irreplaceable. On Tue, Oct 11, 2011 at 7:40 PM, Paulo Pinto wrote: Am 11.10.2011 13:43, schrieb Kagamin: Gor Gyolchanyan Wrote: But this is not gonna happen with such religious attitude to programming. They say built-in arrays are useless, because there's always std::vector and std::list. They say, functional programming and lambdas are useless, because you can make functors and base classes for them. C# is a corporate language and it has no problem with built-in arrays, strings, lambdas and delegates, and constantly introduces new features like linq, generators, covariant templates. True, but you will see seldom things like LINQ or generators being used in corporate projects with offshoring, unless it is somehow required by the APIs being used. Corporate world likes to think of programmers as replaceable items, and that can only be done with simple programming concepts.
Re: std.database design suggestion
Am 11.10.2011 13:37, schrieb Kagamin: bls Wrote: abstract class DatabaseFactory { public abstract Database GetDatabase(); } the method is usually called CreateInstance. I think this is true for the Factory _method_ pattern. I am using the _Abstract_ Factory pattern. See http://en.wikipedia.org/wiki/Abstract_factory_pattern Though createDatabaseInstance () seems to be reasonable/ (follows common coding conventions) -- slightly modified snippet-- import std.stdio; int main(string[] args) { IDatabaseFactory factory; if(args[0] == "MySQL") factory = new MySQLFactory(); else factory = new PostreSQLFactory(); updatePricelist(factory); return 0; } public interface IDatabase { //common database stuff alias open connect; public void open(const string[string] params); //alias close disconnect; //public void close(); // exec(); prepare() etc... } public interface IDatabaseFactory { public IDatabase createDatabaseInstance(); } final class PostgreSQL : IDatabase { // common public void open(const string[string] params) { } //PostgreSQL specific public void funkyPGstuff() {} } final class PostreSQLFactory : IDatabaseFactory { public IDatabase createDatabaseInstance() { return new PostgreSQL(); } } final class MySQL : IDatabase { // common public void open(const string[string] params) { } //MySQL specific public void funkyMySQLstuff() {} } final class MySQLFactory : IDatabaseFactory { public IDatabase createDatabaseInstance() { return new MySQL(); } } // Update PriceList without knowing the db backend void updatePricelist(IDatabaseFactory factory) { IDatabase db = factory.createDatabaseInstance(); db.connect([ "host" : "localhost", "database" : "test", "user" : "bls", "password" : "secret" ]); //db.exec("UPDATE ..."); }
Re: Static arrays, typeof and IFTI?
Andrei Alexandrescu: > I was more enthused about that, but later I realized there are very few > situations in which one reasonably has a fixed-size array that is large > enough to make counting inadequate and is also updated often enough to > make the feature worthwhile. It's one of those features that are nice to > have but are not really missed in real code. I am not going to appreciate a language/compiler that accepts and compiles this program silently. This trap has caused a bug in my code time ago: int[3] a = [1, 2]; void main() {} The usage of [$] in that case avoids that kind of bug... Bye, bearophile
Re: Matrix-type-friendly syntax and more
Gor Gyolchanyan: > I don't think strides are necessary. You can always opApply your image > in a certain way. Define a private struct, which has an opApply, which > iterates over every third channel of each pixel. See: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=146466 > lazy ranges are generally better, then arrays, because with them, you > can avoid copying anything altogether. Strides is just a syntax. The user defined type is later allowed to perform a lazy striding. Bye, bearophile
Re: religious programming
The paradox of good developers is: truly irreplaceable developer is one, that can be easily replaced. The better the developer works, the easier it is to get rid of him. But the one you'll replace him with won't work as good and will make code, which is expensive to understand for newbies. So you won't wanna replace him, which makes him irreplaceable. On Tue, Oct 11, 2011 at 7:40 PM, Paulo Pinto wrote: > Am 11.10.2011 13:43, schrieb Kagamin: >> >> Gor Gyolchanyan Wrote: >> >>> But this is not gonna happen with such religious attitude to programming. >>> They say built-in arrays are useless, because there's always >>> std::vector and std::list. >>> They say, functional programming and lambdas are useless, because you >>> can make functors and base classes for them. >> >> C# is a corporate language and it has no problem with built-in arrays, >> strings, lambdas and delegates, and constantly introduces new features like >> linq, generators, covariant templates. > > True, but you will see seldom things like LINQ or generators being used in > corporate projects with offshoring, unless it is somehow required by > the APIs being used. > > Corporate world likes to think of programmers as replaceable items, and that > can only be done with simple programming concepts. >
Re: religious programming
Le 11/10/2011 17:40, Paulo Pinto a écrit : Am 11.10.2011 13:43, schrieb Kagamin: Gor Gyolchanyan Wrote: But this is not gonna happen with such religious attitude to programming. They say built-in arrays are useless, because there's always std::vector and std::list. They say, functional programming and lambdas are useless, because you can make functors and base classes for them. C# is a corporate language and it has no problem with built-in arrays, strings, lambdas and delegates, and constantly introduces new features like linq, generators, covariant templates. True, but you will see seldom things like LINQ or generators being used in corporate projects with offshoring, unless it is somehow required by the APIs being used. Corporate world likes to think of programmers as replaceable items, and that can only be done with simple programming concepts. No doubt why so many IT project are failures.
Re: religious programming
They ARE replaceable items, because no good programmer would willingly get stuck on the same level for too long. Good programmers tend to grow beyond their current employers all the time. The difference is, that good programmers get replaced by, let's say, the ones, who have a hard time grasping more then one programming technique. On Tue, Oct 11, 2011 at 7:40 PM, Paulo Pinto wrote: > Am 11.10.2011 13:43, schrieb Kagamin: >> >> Gor Gyolchanyan Wrote: >> >>> But this is not gonna happen with such religious attitude to programming. >>> They say built-in arrays are useless, because there's always >>> std::vector and std::list. >>> They say, functional programming and lambdas are useless, because you >>> can make functors and base classes for them. >> >> C# is a corporate language and it has no problem with built-in arrays, >> strings, lambdas and delegates, and constantly introduces new features like >> linq, generators, covariant templates. > > True, but you will see seldom things like LINQ or generators being used in > corporate projects with offshoring, unless it is somehow required by > the APIs being used. > > Corporate world likes to think of programmers as replaceable items, and that > can only be done with simple programming concepts. >
Re: Matrix-type-friendly syntax and more
I don't think strides are necessary. You can always opApply your image in a certain way. Define a private struct, which has an opApply, which iterates over every third channel of each pixel. lazy ranges are generally better, then arrays, because with them, you can avoid copying anything altogether. On Tue, Oct 11, 2011 at 6:36 PM, Robert Jacques wrote: > On Tue, 11 Oct 2011 01:57:06 -0400, kennytm wrote: >> >> "Robert Jacques" wrote: >>> >>> On Mon, 10 Oct 2011 08:46:05 -0400, kennytm wrote: Don wrote: > > On 10.10.2011 04:41, kenji hara wrote: >> >> 2011/10/10 bearophile: >>> >>> So is this: >>> y[$-6, 0..$:2] >>> >>> Translated like this? >>> y.opIndex(y.opDollar!0 - 6, y.opSlice!1(0, y.opDollar!1, 2)) >> >> I have no thought about it. >> I'm not sure that the additional stepping is really useful, but I >> think adding it into syntax is not impossible -- it might not conflict >> with associative array literal. >> >> Kenji Hara > > Personally, I think that since strided operations are so inefficient, > they should remain ugly. Slicing an nD static array is just as in/efficient as strides. That said, I'm still -1 on having a..b:c since (1) I see no practical need for strides and (2) even if we striding it doesn't need to be in the form a..b:c, e.g. arr[stride(0..$, 2)]. >>> >>> Regarding (1), from a computer vision/graphics perspective, being able to >>> only operate on the red channel, for example, is very nice. And I use >>> striding all the time in my CUDA code, but that's not as applicable in D, >>> yet. Striding tends to be most useful for working with packed data of >>> some kind. >> >> Why not use a 'Color' struct? >> > > Not all images have the same layout, so having a single Color struct doesn't > cut it. (RGB, RGBA, BGR, BGRA, ARGB, ABGR) Although, being able to say: > structArr[0..$].red; would be very handy indeed. But all that is / should be > is a opDispatch wrapper around a strided operation: byteArr[2..$:3] >
Re: about const and immutable (again)
assert(is(typeof(&foo) : void function(int)); On Tue, Oct 11, 2011 at 6:35 PM, Steven Schveighoffer wrote: > On Mon, 10 Oct 2011 21:29:08 -0400, Andrei Alexandrescu > wrote: > >> On 10/10/11 5:55 PM, Don wrote: >>> >>> On 06.10.2011 20:56, Steven Schveighoffer wrote: On Thu, 06 Oct 2011 12:27:16 -0400, Gor Gyolchanyan wrote: > I see. Thanks for the detailed answer. I should clarify one point, I realized I am somewhat inaccurate on the reason the type is set to immutable(dchar). In fact, nobody actually wrote the immutable(dchar) function, it's just that the element type is immutable(dchar). However, the reasons why someone would want to create a function that takes an immutable(dchar) function are as I stated -- so you don't accidentally change the value. >>> >>> That seems like the discussed-and-discarded 'final' storage class for >>> parameters. But this is worse. It has an *enormous* cost. >> >> Walter and I have agreed for a long time that upon function calls with >> by-value passing, there should be some simple transforms done: >> >> 1. If a parameter has no indirections, qual(T) becomes T. >> >> 2. qual(T[]) becomes qual(T)[]. >> >> 3. qual(T*) becomes qual(T)*. >> >> This would improve many aspects of the language. Walter never got to >> implementing it, but I'm bringing this up in case one of the wonderful >> compiler contributors would want to take it up. Again, I have reasons to >> believe Walter would approve of the change. > > I agree, this would help tremendously. Would this apply to function > pointers/delegates as well? For example: > > void foo(const(int) i) {} > > assert(is(typeof(&foo) == void function(int)); > > I would prefer it not be this way, and rather start defining some implicit > delegate/function casting. I think D really needs this, not just in the > area of const. > > -Steve >
Re: religious programming
Am 11.10.2011 13:43, schrieb Kagamin: Gor Gyolchanyan Wrote: But this is not gonna happen with such religious attitude to programming. They say built-in arrays are useless, because there's always std::vector and std::list. They say, functional programming and lambdas are useless, because you can make functors and base classes for them. C# is a corporate language and it has no problem with built-in arrays, strings, lambdas and delegates, and constantly introduces new features like linq, generators, covariant templates. True, but you will see seldom things like LINQ or generators being used in corporate projects with offshoring, unless it is somehow required by the APIs being used. Corporate world likes to think of programmers as replaceable items, and that can only be done with simple programming concepts.
Re: questions: remove from SList
On Tue, 11 Oct 2011 05:19:41 -0400, enuhtac wrote: Hello, I have two issues removing items from a SList. Consider following code: import std.container; import std.algorithm; void main() { SList!int a = [ 5, 4, 3, 2, 1 ]; auto r = a[]; remove( r, 2 ); // ERROR! Needed member function are not // implemented by SList(T).Range a.remove( r ); // ERROR! There is no member function remove } * The call to algorithm.remove produces these error messages: /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: src.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: tgt.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5954): Error: no property 'popFrontN' for type 'Range' /usr/include/d/dmd/phobos/std/algorithm.d(5956): Error: no property 'popBack' for type 'Range' I would presume that phobos algorithms should work for all phobos containers, right? - At least if the prerequisites are met. The relevant prerequisite for this version of "remove" is "isForwardRange!Range" which is clearly the case for SList(T).Range. Nevertheless "remove" tries to access "popFrontN" and "popBack" which are not part of the ForwardRange specification. The lvalue-errors are another issue. I would clearly say this implementation of remove is buggy - or am I wrong? Yes, I'd agree either remove's implementation or its constraint specification are buggy. It should not specify that it needs a forward range and then use bi-directional range primitives. However, I don't think std.algorithm.remove does what you want, I think it moves data that is not desired to the end of the range (not exactly sure). * The second call to remove does not succeed because there is no member function "remove". Instead there is "linearRemove". This is not a bug of course. But if I want to write code that uses some unspecific container it is very inconvenient that instead of "remove" I might have to call "linearRemove" or "stableRemove". Why not add a simple alias linearRemove remove ? The exact point of why SList contains linearRemove and not remove is so that code which expects sub-linear remove function will not compile for SList, because SList does not support quick removal. Aliasing remove to linearRemove would defeat the purpose of using function names to imply complexity and side-effects, which is one of the main charters of std.container. There's always dcollections ;) http://www.dsource.org/projects/dcollections -Steve
Re: Static arrays, typeof and IFTI?
On Mon, 10 Oct 2011 02:42:26 -0400, Norbert Nemec wrote: Hi there, after a very busy and eventful year in my personal life, I have now finally found some time to play with D2. I am very impressed by the progress! One thing I noticed was that static arrays are somehow strangely limited: It is possible to overload based on the length: void f(int[3] x) { writeln("int[3]: ",x); } void f(int[4] x) { writeln("int[4]: ",x); } int main(string argv[]) { f([1,2,3]); f([1,2,3,4]); return 0; } However, used as function template argument, a static array is casted to a dynamic array: --- void g(T)(T x) { static assert (__traits(isStaticArray,T)); enum N = T.init.length; writeln(N,": ",x); } int main(string argv[]) { g([1,2,3]); return 0; } gives the error message: | Error: static assert (__traits(isStaticArray,int[])) is false | instantiated from here: g!(int[]) Without the assertion, N is defined to 0. Further investigation shows: --- g!(int[3])([1,2,3]); // passes a static array --- int[3] x3 = [1,2,3]; g(x3);// passes a static array --- auto z3 = [1,2,3];// defines z3 as dynamic array g(y3);// passes a dynamic array --- So it seems, the problem is that array literals on their own turned into dynamic arrays unless you explicitly state a static array type in some way. In fact, all array literals are dynamic. Examine the code for g!(int[3])([1,2,3]) (comments added): push3 push2 push1 push3 mov EAX,offset FLAT:_D12TypeInfo_G3i6__initZ@SYM32 pushEAX call _d_arrayliteralT@PC32 ; create dynamic array literal add ESP,014h mov EBX,EAX pushdword ptr 8[EBX] ; copy the data from the heap-allocated literal into the fixed-sized array temporary pushdword ptr 4[EBX] pushdword ptr [EBX] call _D10testdynarr10__T1gTG3iZ1gFG3iZv@PC32 ; call g So really, the situation is worse than you thought :) Wouldn't it make more sense the other way around? After all, turning a static array into a dynamic array is easy, the other way around is prohibited by the compiler. If array literals simply had a static array type, they could be implicitly casted to dynamic arrays when necessary but stay static if possible. D1 I think works that way (array and string literals are fixed-sized array arrays). Most of the time, you don't want a static array to be passed. Remember that fixed-size arrays are passed by *value* not by reference. This means any large array will be fully pushed onto the stack to pass it, not just a slice. It also adds (most of the time unnecessarily) bloat. Think of string literals: foo(T)(T x) { writeln(x); } foo("hello"); foo("goodbye"); In D1, this creates *two* different instantiations of foo, one for char[5u] and one for char[7u]. In D2 if fixed-sized array were the default choice, both "hello" and "goodbye" would be passed by value, meaning pushing all the data on the stack, in addition to creating the bloat. I do agree writing a fixed-size array literal should be easier than it is. -Steve
Re: Matrix-type-friendly syntax and more
On Tue, 11 Oct 2011 01:57:06 -0400, kennytm wrote: "Robert Jacques" wrote: On Mon, 10 Oct 2011 08:46:05 -0400, kennytm wrote: Don wrote: On 10.10.2011 04:41, kenji hara wrote: 2011/10/10 bearophile: So is this: y[$-6, 0..$:2] Translated like this? y.opIndex(y.opDollar!0 - 6, y.opSlice!1(0, y.opDollar!1, 2)) I have no thought about it. I'm not sure that the additional stepping is really useful, but I think adding it into syntax is not impossible -- it might not conflict with associative array literal. Kenji Hara Personally, I think that since strided operations are so inefficient, they should remain ugly. Slicing an nD static array is just as in/efficient as strides. That said, I'm still -1 on having a..b:c since (1) I see no practical need for strides and (2) even if we striding it doesn't need to be in the form a..b:c, e.g. arr[stride(0..$, 2)]. Regarding (1), from a computer vision/graphics perspective, being able to only operate on the red channel, for example, is very nice. And I use striding all the time in my CUDA code, but that's not as applicable in D, yet. Striding tends to be most useful for working with packed data of some kind. Why not use a 'Color' struct? Not all images have the same layout, so having a single Color struct doesn't cut it. (RGB, RGBA, BGR, BGRA, ARGB, ABGR) Although, being able to say: structArr[0..$].red; would be very handy indeed. But all that is / should be is a opDispatch wrapper around a strided operation: byteArr[2..$:3]
Re: about const and immutable (again)
On Mon, 10 Oct 2011 21:29:08 -0400, Andrei Alexandrescu wrote: On 10/10/11 5:55 PM, Don wrote: On 06.10.2011 20:56, Steven Schveighoffer wrote: On Thu, 06 Oct 2011 12:27:16 -0400, Gor Gyolchanyan wrote: I see. Thanks for the detailed answer. I should clarify one point, I realized I am somewhat inaccurate on the reason the type is set to immutable(dchar). In fact, nobody actually wrote the immutable(dchar) function, it's just that the element type is immutable(dchar). However, the reasons why someone would want to create a function that takes an immutable(dchar) function are as I stated -- so you don't accidentally change the value. That seems like the discussed-and-discarded 'final' storage class for parameters. But this is worse. It has an *enormous* cost. Walter and I have agreed for a long time that upon function calls with by-value passing, there should be some simple transforms done: 1. If a parameter has no indirections, qual(T) becomes T. 2. qual(T[]) becomes qual(T)[]. 3. qual(T*) becomes qual(T)*. This would improve many aspects of the language. Walter never got to implementing it, but I'm bringing this up in case one of the wonderful compiler contributors would want to take it up. Again, I have reasons to believe Walter would approve of the change. I agree, this would help tremendously. Would this apply to function pointers/delegates as well? For example: void foo(const(int) i) {} assert(is(typeof(&foo) == void function(int)); I would prefer it not be this way, and rather start defining some implicit delegate/function casting. I think D really needs this, not just in the area of const. -Steve
Re: "static interface" for structs
You can have those protocols: import("my_protocol.pr"); mixin(parseProtocol(protocol)), etc... On Tue, Oct 11, 2011 at 6:24 PM, Gor Gyolchanyan wrote: > BTW, you can make a template, which takes an interface type and a > struct type and evaluates to a bool, indicating whether the struct > theoretically implements the interface. > I actually had a success in doing something similar. > Here are the main features I use in these situations: > __traits(allMembers, Type); > is(typeof(member)) > __traits(getOverloads, Type); > > On Tue, Oct 11, 2011 at 6:01 PM, Andrej Mitrovic > wrote: >> On 10/11/11, Gor Gyolchanyan wrote: >>> Actually, the __traits(compiles, ...) is a marvelous and very powerful >>> tool that will allow you to test if the struct is fit for your >>> particular task by just specifying the task. >> >> Yeah, but you have to write very specific code to test if it really is >> a compatible type. And even after all that hard work you could still >> easily pass a type that "walks like a duck" but that you know is >> actually incompatible. So then you have to write specific if(!is(T == >> IncompatibleType)), and this doesn't scale too well. >> >> This is why I resort to having an enum boolean as the first field of a >> struct that defines its "protocol", but I really see that as a >> poor-man's implementation of interfaces. >> >
Re: "static interface" for structs
BTW, you can make a template, which takes an interface type and a struct type and evaluates to a bool, indicating whether the struct theoretically implements the interface. I actually had a success in doing something similar. Here are the main features I use in these situations: __traits(allMembers, Type); is(typeof(member)) __traits(getOverloads, Type); On Tue, Oct 11, 2011 at 6:01 PM, Andrej Mitrovic wrote: > On 10/11/11, Gor Gyolchanyan wrote: >> Actually, the __traits(compiles, ...) is a marvelous and very powerful >> tool that will allow you to test if the struct is fit for your >> particular task by just specifying the task. > > Yeah, but you have to write very specific code to test if it really is > a compatible type. And even after all that hard work you could still > easily pass a type that "walks like a duck" but that you know is > actually incompatible. So then you have to write specific if(!is(T == > IncompatibleType)), and this doesn't scale too well. > > This is why I resort to having an enum boolean as the first field of a > struct that defines its "protocol", but I really see that as a > poor-man's implementation of interfaces. >
Re: "static interface" for structs
Right. It is far too verbose, but those protocols are too restrictive. With no run-time value, the protocols must be very flexible to contain any kind of requirements on structs, that are practically useful to have. The __traits(compiles, ...) would be awesome to be automatically be used in templates: void func(Type)(Type param) { Type temp = new Type; temp.method(param); } This code requires the Type to be either a class or a struct with a this(typeof(this)*) { } implemented in it. If the test for it was automatically included in the template's constraint, it would make templates so much easier to use. Templates would then overload on their bodies. You'd just write several implementations of the template and the correct one would be automatically chosen, based on the implementation itself. And in case none of them are applicable, the compiler would be able to tell you exactly what does your template parameter lack. But we don't have that, unfortunately. On Tue, Oct 11, 2011 at 6:01 PM, Andrej Mitrovic wrote: > On 10/11/11, Gor Gyolchanyan wrote: >> Actually, the __traits(compiles, ...) is a marvelous and very powerful >> tool that will allow you to test if the struct is fit for your >> particular task by just specifying the task. > > Yeah, but you have to write very specific code to test if it really is > a compatible type. And even after all that hard work you could still > easily pass a type that "walks like a duck" but that you know is > actually incompatible. So then you have to write specific if(!is(T == > IncompatibleType)), and this doesn't scale too well. > > This is why I resort to having an enum boolean as the first field of a > struct that defines its "protocol", but I really see that as a > poor-man's implementation of interfaces. >
Re: religious programming
Very good point. In fact, I used to be very religious about C++ and i never wanted to use anything else besides it. Interestingly enough I was the one to propose to move our project to D (my brother and I are working on our own projects). Even since, he doesn't stop telling me how awesome D is (after having 9+ years of C++ experience). The only way for me (and all others, that agree with me in this) is to start their own projects and get self-employed. I'm a run-time performance freak. I want to push my code to the ultimate limit of performance, which will allow me to use many seemingly expensive features at once and benefit from unprecedented functionality (which is unprecedented because of the performance limitations). The biggest source of performance hit is workarounds and adapters. Java is so slow not only because of it's "RAM is cheaper, then CPU" policy, but also because it's filled with OO adapters around non-OO concepts. D is by far the least adapter-hungry software development tool I ever saw. D has a "right way" to do everything, as opposed to, let's say, Java's "right way" to implement hierarchically related sets of data and functions to manipulate them, but with no way to do anything else, which makes everything else being implemented the "wrong way". All I want in this respect is to get rid of workarounds, adapters and "wrong way" of getting things done. And i can't help but notice, that i highly depend of other people's work (libraries I use, programmers I'll hire). That's why I want to help people stop making layers after layers after layers of wrappers around a smelly implementation to try and cover up the smell and start doing it the way it was supposed to be done. On Tue, Oct 11, 2011 at 5:22 PM, deadalnix wrote: > Le 11/10/2011 11:57, Gor Gyolchanyan a écrit : >> >> I can't keep it in any more, I have to share. >> >> The code is unimaginably bloated, flooded with thousands of tiny >> redundant classes, each of which do a primitive task, which doesn't >> need to be a class at all. > > Well, you'll have to admit that you are a religious yourself. I currently > facing problems with that state of mind, trying to put back a project on > track. > > This lread to very difficult code to maintain and make evolve. The key point > here is separation of concerns. Even if you have to write a function with 2 > lines of payload, it will pay in maintenance, testing , debug and future > evolutions. > > That said, I face often the other argument : this class/function/whatever is > too big. Well if the function contains a damn procedure that the program > must follow step by step, a long function is definitvely the way. Separation > of concern as usual. > > This doesn't means you software will be bloated. You can use metaprogramming > to assemble all thoses parts at compile time. > > I'm also sometime facing religious behaviour of mine. We all do that. The > key is to be ready to open up when a logical argument is proposed. This is > the way you evolve. > > Back on the subject, company policies are often made by so called senior > programmers, that did the same mistakes again and again and again for years > and enforce them in the company throw policies. This is a fact, most people > hate change, and will do whatever they can to avoid it (if you are > interested on the topic, this is broadly studied by psychologists). You'll > have a natural tendancy to do that yourself, it is natural. Fight it every > day to be a better programmer :D > > The 100% OOP iritate me too (and a part of my job is in java) but it has the > advantage to avoid people to learn new concept. Sadly, this is what they > want. And this is sometime what is better for the company, because you don't > want to work against your employee. They will be demotivated and > unproductive, but worse, reluctant to do good quality work. > > Back to company, I did myself showed to management that I was very > productive and did quality code (less bugs, easier to evolve to includ enew > functions). This is important to show that by RESULTS. When you have data > and facts, you can push good practices in the company. > > Now we got better working conditions (better hardware, better workspace, etc > . . .) and are way more exigent on new employee capacities (especially > thoses who worked with non mainstream technologies like D obviously, but > also haskell, erlang, or basically anything that show curiosity and eager to > learn new stuff and get better). And this is working. > > Remembrer : if you can't change the place, just move. IT gives a lot of > opportunities. By many of them will be in similar conditions than your > current position. You usually have to change the company or be very lucky to > find one which already know what software is about. >
Re: "static interface" for structs
On 10/11/11, Gor Gyolchanyan wrote: > Actually, the __traits(compiles, ...) is a marvelous and very powerful > tool that will allow you to test if the struct is fit for your > particular task by just specifying the task. Yeah, but you have to write very specific code to test if it really is a compatible type. And even after all that hard work you could still easily pass a type that "walks like a duck" but that you know is actually incompatible. So then you have to write specific if(!is(T == IncompatibleType)), and this doesn't scale too well. This is why I resort to having an enum boolean as the first field of a struct that defines its "protocol", but I really see that as a poor-man's implementation of interfaces.
Re: "static interface" for structs
Actually, the __traits(compiles, ...) is a marvelous and very powerful tool that will allow you to test if the struct is fit for your particular task by just specifying the task. On Tue, Oct 11, 2011 at 4:30 PM, Marco Leise wrote: > First things first: I've been told on IRC that this idea has already come up > and was rejected in favor of template guards. But it wasn't clear what the > reasons were. > > The idea is to have "static interface" or "protocol" for structs similar to > the "interface" for classes. The benefit comes from the fact that in D we > often see structs used in a way other languages can't. A prime example are > function templates for sorting algorithms that can take any kind of range > (built-in, class, struct). But with this broader use, comes the need to be > explicit about the interface of a struct akin to interfaces for classes. A > compiler or IDE can detect missing or incorrectly spelled methods on structs > that implement a protocol. Readers of your code can understand from the > declaration that a struct is forward-iterable or supports some other > protocol. > > These are the rules: > 1. Protocols share the common symbol space with classes, interfaces, etc. > 2. They can be (multiple-)inherited by interfaces and other protocols. > 3. They can be implemented by structs as well as classes. > > I use "protocol" as a keyword to avoid any confusion with what "interface" > allows you to do at runtime. Also this is not "C++ concepts" in disguise. > Actually I didn't know about until now. It is somewhat of a really small > subset of that though. > > > protocol InputRange(E) { > @property bool empty; > @property E front; > E popFront(); > } > > // defines a property that returns the declared range type > protocol ForwardRange(E) : InputRange!E { > @property typeof(this) save; > } > > // just a tag > protocol InfiniteRange(E) : ForwardRange!E {} > > > I used the range module as an example, just because it is the first that > came to my head. Actually on browsing the source for a while I realized that > checks like "hasLength", which look like a candidate for a protocol are more > flexible than a method/field declaration. length can be a field or property > and return any integral type. So on 32-bit systems it works with 64-bit file > sizes and 32-bit indexes on arrays just as well. So even if protocols make > for a nice syntax, they don't fit the bill. Other ideas for struct > "interfaces"? >
Re: Static arrays, typeof and IFTI?
On 10/11/11 2:56 AM, bearophile wrote: Norbert Nemec: However there does not seem to be any way to state int[...whatever...] myvar = [1,2,3,4]; enum N = typeof(myvar).init.length; and let the compiler deduce that N==4. Since years some people (among them there is me too) are asking for this syntax: int arr[$] = [1,2,3,4]; Vote for it here (an enhancement request from 2006!): http://d.puremagic.com/issues/show_bug.cgi?id=481 I was more enthused about that, but later I realized there are very few situations in which one reasonably has a fixed-size array that is large enough to make counting inadequate and is also updated often enough to make the feature worthwhile. It's one of those features that are nice to have but are not really missed in real code. Andrei
Re: [std.database]
On 10/10/11 11:02 PM, Robert Jacques wrote: On Mon, 10 Oct 2011 11:09:34 -0400, Andrei Alexandrescu wrote: On 10/10/11 7:01 AM, Steve Teale wrote: [snip] That's a bug in std.variant. Large structs should be supported automatically by using an indirection and dynamic allocation. For what it's worth, my improved Variant proposal, does do that. (i.e. it fixes the bug) Is it ready for review? Andrei
Re: religious programming
Le 11/10/2011 11:57, Gor Gyolchanyan a écrit : I can't keep it in any more, I have to share. The code is unimaginably bloated, flooded with thousands of tiny redundant classes, each of which do a primitive task, which doesn't need to be a class at all. Well, you'll have to admit that you are a religious yourself. I currently facing problems with that state of mind, trying to put back a project on track. This lread to very difficult code to maintain and make evolve. The key point here is separation of concerns. Even if you have to write a function with 2 lines of payload, it will pay in maintenance, testing , debug and future evolutions. That said, I face often the other argument : this class/function/whatever is too big. Well if the function contains a damn procedure that the program must follow step by step, a long function is definitvely the way. Separation of concern as usual. This doesn't means you software will be bloated. You can use metaprogramming to assemble all thoses parts at compile time. I'm also sometime facing religious behaviour of mine. We all do that. The key is to be ready to open up when a logical argument is proposed. This is the way you evolve. Back on the subject, company policies are often made by so called senior programmers, that did the same mistakes again and again and again for years and enforce them in the company throw policies. This is a fact, most people hate change, and will do whatever they can to avoid it (if you are interested on the topic, this is broadly studied by psychologists). You'll have a natural tendancy to do that yourself, it is natural. Fight it every day to be a better programmer :D The 100% OOP iritate me too (and a part of my job is in java) but it has the advantage to avoid people to learn new concept. Sadly, this is what they want. And this is sometime what is better for the company, because you don't want to work against your employee. They will be demotivated and unproductive, but worse, reluctant to do good quality work. Back to company, I did myself showed to management that I was very productive and did quality code (less bugs, easier to evolve to includ enew functions). This is important to show that by RESULTS. When you have data and facts, you can push good practices in the company. Now we got better working conditions (better hardware, better workspace, etc . . .) and are way more exigent on new employee capacities (especially thoses who worked with non mainstream technologies like D obviously, but also haskell, erlang, or basically anything that show curiosity and eager to learn new stuff and get better). And this is working. Remembrer : if you can't change the place, just move. IT gives a lot of opportunities. By many of them will be in similar conditions than your current position. You usually have to change the company or be very lucky to find one which already know what software is about.
"static interface" for structs
First things first: I've been told on IRC that this idea has already come up and was rejected in favor of template guards. But it wasn't clear what the reasons were. The idea is to have "static interface" or "protocol" for structs similar to the "interface" for classes. The benefit comes from the fact that in D we often see structs used in a way other languages can't. A prime example are function templates for sorting algorithms that can take any kind of range (built-in, class, struct). But with this broader use, comes the need to be explicit about the interface of a struct akin to interfaces for classes. A compiler or IDE can detect missing or incorrectly spelled methods on structs that implement a protocol. Readers of your code can understand from the declaration that a struct is forward-iterable or supports some other protocol. These are the rules: 1. Protocols share the common symbol space with classes, interfaces, etc. 2. They can be (multiple-)inherited by interfaces and other protocols. 3. They can be implemented by structs as well as classes. I use "protocol" as a keyword to avoid any confusion with what "interface" allows you to do at runtime. Also this is not "C++ concepts" in disguise. Actually I didn't know about until now. It is somewhat of a really small subset of that though. protocol InputRange(E) { @property bool empty; @property E front; E popFront(); } // defines a property that returns the declared range type protocol ForwardRange(E) : InputRange!E { @property typeof(this) save; } // just a tag protocol InfiniteRange(E) : ForwardRange!E {} I used the range module as an example, just because it is the first that came to my head. Actually on browsing the source for a while I realized that checks like "hasLength", which look like a candidate for a protocol are more flexible than a method/field declaration. length can be a field or property and return any integral type. So on 32-bit systems it works with 64-bit file sizes and 32-bit indexes on arrays just as well. So even if protocols make for a nice syntax, they don't fit the bill. Other ideas for struct "interfaces"?
Re: religious programming
You're the second person to say I'm also religious, but you miss the point of religious programming: I'm always open to new techniques. I constantly research for new and better ways of doing what I'm about to do. My approach to getting things done is dynamic and i never praise my techniques as the best in the world and fit for every purpose. About troubles at home and effort: It doesn't take much effort to learn a language. It doesn't take much effort to pay attention to the code you read and write. It's just a matter of a habit. Some people are careful, some people are sloppy, some people are progressive, some people are lazy. I have my own family to take care of and I have my own projects to develop, but it doesn't stop me from being careful and neat with what i write. It's just a matter of a habit. About paradigms. The need for a limited language comes form the fact, that people don't write maintainable code. Even if a team uses C++ with lots of address arithmetic and obscure type casts it's always possible to make it easy to read. Every level of programming and every paradigm has it's ways of writing a neat and maintainable code. On Tue, Oct 11, 2011 at 3:39 PM, bearophile wrote: > Gor Gyolchanyan: > >> Can anyone help me out in this quest of enlightening people? > > Talking about "enlightening people" means assuming a bad starting point, > where you are as much religious as them. > > And regarding them, I think that reading books and articles helps widen the > mind a bit. But people have families, children and many hours of work every > day. They are often stopped training their brains as they used to do in very > good schools. Pushing new knowledge into a middle aged brain requires energy > and a bit of pain, not everyone is willing to endure this year after year, in > presence of all other kinds of family and work and health problems. Reducing > the amount of daily work hours to something like 6 helps leave some time to > read books too. > > --- > > Marco Leise: > >>The point is, that companies want a language that does things one way. It is >>easy to share code this way and to train programmers in that language. There >>is no "oh what is that construct doing?" in Java because the language is >>primitive and pretty verbose. It is also easier for me to only have a few >>concepts in my head when I write code.< > > When I program in D I often find several different ways to solve a problem, > with a functional, or with an OOP solution, or with a high level one, or with > a lower level one, or with generic code. Often my first solution is not the > best, and I rewrite the code in a different way. A language that offers only > one programming paradigm avoids this, and this is has its advantages. > > Single-paradigm languages (Smalltalk, Haskell) and multi-paradigm ones (Oz, > D, Scala) have both advantages and disadvantages. A language like Scala (and > in past CommonLisp) is very good in the hands of an expert programmer, able > to make it sing like a Stradivari violin. But in the hands of a less skilled > programmer, or a skilled programmer that needs to write certain commercial > programs, a less flexible language is often better. > > Regarding Java, it's simpler, but this is especially true if you have to use > it to solve simple problems. If you have to implement a complex algorithm > that works with differently shaped trees, efficiently, doing pattern matching > on them, etc, then a language like OcaML becomes more appreciable that what > it usually is. > > The Java simplicity forces you to push part of the program complexity out of > the language and into conventions, patterns, IDE skills, IDE shorcuts, that > increase again the apparent simplicity of Java coding. Generally it's hard to > destroy the complexity, you often just move it around. > > Bye, > bearophile >
Re: religious programming
Gor Gyolchanyan Wrote: > But this is not gonna happen with such religious attitude to programming. > They say built-in arrays are useless, because there's always > std::vector and std::list. > They say, functional programming and lambdas are useless, because you > can make functors and base classes for them. C# is a corporate language and it has no problem with built-in arrays, strings, lambdas and delegates, and constantly introduces new features like linq, generators, covariant templates.
Re: std.database design suggestion
bls Wrote: > abstract class DatabaseFactory { > > public abstract Database GetDatabase(); > } the method is usually called CreateInstance.
Re: religious programming
Gor Gyolchanyan: > Can anyone help me out in this quest of enlightening people? Talking about "enlightening people" means assuming a bad starting point, where you are as much religious as them. And regarding them, I think that reading books and articles helps widen the mind a bit. But people have families, children and many hours of work every day. They are often stopped training their brains as they used to do in very good schools. Pushing new knowledge into a middle aged brain requires energy and a bit of pain, not everyone is willing to endure this year after year, in presence of all other kinds of family and work and health problems. Reducing the amount of daily work hours to something like 6 helps leave some time to read books too. --- Marco Leise: >The point is, that companies want a language that does things one way. It is >easy to share code this way and to train programmers in that language. There >is no "oh what is that construct doing?" in Java because the language is >primitive and pretty verbose. It is also easier for me to only have a few >concepts in my head when I write code.< When I program in D I often find several different ways to solve a problem, with a functional, or with an OOP solution, or with a high level one, or with a lower level one, or with generic code. Often my first solution is not the best, and I rewrite the code in a different way. A language that offers only one programming paradigm avoids this, and this is has its advantages. Single-paradigm languages (Smalltalk, Haskell) and multi-paradigm ones (Oz, D, Scala) have both advantages and disadvantages. A language like Scala (and in past CommonLisp) is very good in the hands of an expert programmer, able to make it sing like a Stradivari violin. But in the hands of a less skilled programmer, or a skilled programmer that needs to write certain commercial programs, a less flexible language is often better. Regarding Java, it's simpler, but this is especially true if you have to use it to solve simple problems. If you have to implement a complex algorithm that works with differently shaped trees, efficiently, doing pattern matching on them, etc, then a language like OcaML becomes more appreciable that what it usually is. The Java simplicity forces you to push part of the program complexity out of the language and into conventions, patterns, IDE skills, IDE shorcuts, that increase again the apparent simplicity of Java coding. Generally it's hard to destroy the complexity, you often just move it around. Bye, bearophile
Re: religious programming
Hi, you fail to see why this is this way. Corporate code does not have a soul. Every code line needs to be understood by everyone. Regardless if they have a PhD in computer science or just learned programming on the weekends. Plus the code needs to be simple enough, so that in the course of few months you are able to transfer code ownership to any country in the world, depending on project budget. This is one of the main reasons why the so called "blue collar" languages like Java thrive in the enterprise world. I don't like this, but it won't change. If I sound too harsh, maybe I just had too many corporate projects in my life. -- Paulo "Gor Gyolchanyan" wrote in message news:mailman.37.1318327068.24802.digitalmar...@puremagic.com... >I can't keep it in any more, I have to share. > > I've seen lots of corporate C++ code and coding guidelines and I came > to the conclusion, that they're all bogus. > The vast majority of code, being written in commercial projects use a > very limited subset of the language they use. > The code I work with currently is a purely object-oriented C++ code. > I used to like object-oriented programming until I started working > with that code. > Corporate code is very religious. They use a few specialized > techniques for everything. > They use object-oriented programming when functional programming is > the technique of choice. > They use object-oriented programming when generic programming is the > technique of choice. > The code is unimaginably bloated, flooded with thousands of tiny > redundant classes, each of which do a primitive task, which doesn't > need to be a class at all. > I've discussed D with my colleagues lately and the vast multi-paradigm > and built-in featured of D were discarded with a religious "There's a > class already written for that.". > Why do I keep saying "religious"? Because they are convinced, that > this is the way to go and do not accept any logical arguments. > Why do I talk about this at all? Because corporate code is the one we > need to become D. > But this is not gonna happen with such religious attitude to programming. > They say built-in arrays are useless, because there's always > std::vector and std::list. > They say, functional programming and lambdas are useless, because you > can make functors and base classes for them. > They say garbage collection is useless, because there's always > std::shared_ptr. > Well, yes. You do have all that. But look what the code looks like and > how fast it runs! > > It's amazing how stupid and ignorant can corporate developers be > sometimes and how smart and considerate open-source developers can be. > I don't know how to cure the people's minds from this religious > plague, that poisons the software development industry. > > Can anyone help me out in this quest of enlightening people?
Re: religious programming
You got good points. Java is indeed a very simple and safe language. But it's a straitjacket. Java is filled with techniques, developed as workarounds to compensate for the lack of other paradigms. All the arguments about ease of collaborative development comes from developers' unwillingness to learn and pay attention. At this rate the entire software industry could be build on the idea that no-one wants to work properly. On Tue, Oct 11, 2011 at 2:38 PM, Marco Leise wrote: > Am 11.10.2011, 11:57 Uhr, schrieb Gor Gyolchanyan > : > >> I don't know how to cure the people's minds from this religious >> plague, that poisons the software development industry. >> >> Can anyone help me out in this quest of enlightening people? > > So you want to convert the barbarians? Then you must accept, that you > yourself are a religious person about multi-paradigm programming. Yes the > devil lies within everyone of us. I have been writing code in Java and it is > OOP exclusively. The point is, that companies want a language that does > things one way. It is easy to share code this way and to train programmers > in that language. There is no "oh what is that construct doing?" in Java > because the language is primitive and pretty verbose. It is also easier for > me to only have a few concepts in my head when I write code. Maybe it is > also the way I'm wired. Everything is an object the has to do X and works > together with Y and Z is a concept that I can easily apply to almost > everything. > > If these C++ programmers you talk about like the restrictive use of language > features, then you should respect that. They may have had a hard in the past > with people writing code like Picasso. I mean, good code that uses features > that were difficult for others to understand at first. If you don't > understand other people's code you are likely to introduce bugs. As long as > they aren't open to what really makes them stick to their style rules and > language it is hard to say what would make them consider D. After all the > pitfalls in D will be more confusing to them coming from C++ than any C++ > code could ever be. > > Maybe they like the integrated unit tests. I've heard people are more likely > to actually write them if they are integrated like that. Or at some point > they say "if I could just define what the object state must be after this > public method exits I wouldn't have this bug now!" and contracts come into > play. Anyway, don't put C++ down unless they are open to speak about what > they wish for and are willing to accept new ideas. >
Re: religious programming
Am 11.10.2011, 11:57 Uhr, schrieb Gor Gyolchanyan : I don't know how to cure the people's minds from this religious plague, that poisons the software development industry. Can anyone help me out in this quest of enlightening people? So you want to convert the barbarians? Then you must accept, that you yourself are a religious person about multi-paradigm programming. Yes the devil lies within everyone of us. I have been writing code in Java and it is OOP exclusively. The point is, that companies want a language that does things one way. It is easy to share code this way and to train programmers in that language. There is no "oh what is that construct doing?" in Java because the language is primitive and pretty verbose. It is also easier for me to only have a few concepts in my head when I write code. Maybe it is also the way I'm wired. Everything is an object the has to do X and works together with Y and Z is a concept that I can easily apply to almost everything. If these C++ programmers you talk about like the restrictive use of language features, then you should respect that. They may have had a hard in the past with people writing code like Picasso. I mean, good code that uses features that were difficult for others to understand at first. If you don't understand other people's code you are likely to introduce bugs. As long as they aren't open to what really makes them stick to their style rules and language it is hard to say what would make them consider D. After all the pitfalls in D will be more confusing to them coming from C++ than any C++ code could ever be. Maybe they like the integrated unit tests. I've heard people are more likely to actually write them if they are integrated like that. Or at some point they say "if I could just define what the object state must be after this public method exits I wouldn't have this bug now!" and contracts come into play. Anyway, don't put C++ down unless they are open to speak about what they wish for and are willing to accept new ideas.
religious programming
I can't keep it in any more, I have to share. I've seen lots of corporate C++ code and coding guidelines and I came to the conclusion, that they're all bogus. The vast majority of code, being written in commercial projects use a very limited subset of the language they use. The code I work with currently is a purely object-oriented C++ code. I used to like object-oriented programming until I started working with that code. Corporate code is very religious. They use a few specialized techniques for everything. They use object-oriented programming when functional programming is the technique of choice. They use object-oriented programming when generic programming is the technique of choice. The code is unimaginably bloated, flooded with thousands of tiny redundant classes, each of which do a primitive task, which doesn't need to be a class at all. I've discussed D with my colleagues lately and the vast multi-paradigm and built-in featured of D were discarded with a religious "There's a class already written for that.". Why do I keep saying "religious"? Because they are convinced, that this is the way to go and do not accept any logical arguments. Why do I talk about this at all? Because corporate code is the one we need to become D. But this is not gonna happen with such religious attitude to programming. They say built-in arrays are useless, because there's always std::vector and std::list. They say, functional programming and lambdas are useless, because you can make functors and base classes for them. They say garbage collection is useless, because there's always std::shared_ptr. Well, yes. You do have all that. But look what the code looks like and how fast it runs! It's amazing how stupid and ignorant can corporate developers be sometimes and how smart and considerate open-source developers can be. I don't know how to cure the people's minds from this religious plague, that poisons the software development industry. Can anyone help me out in this quest of enlightening people?
questions: remove from SList
Hello, I have two issues removing items from a SList. Consider following code: import std.container; import std.algorithm; void main() { SList!int a = [ 5, 4, 3, 2, 1 ]; auto r = a[]; remove( r, 2 ); // ERROR! Needed member function are not // implemented by SList(T).Range a.remove( r ); // ERROR! There is no member function remove } * The call to algorithm.remove produces these error messages: /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: src.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5951): Error: tgt.front() is not an lvalue /usr/include/d/dmd/phobos/std/algorithm.d(5954): Error: no property 'popFrontN' for type 'Range' /usr/include/d/dmd/phobos/std/algorithm.d(5956): Error: no property 'popBack' for type 'Range' I would presume that phobos algorithms should work for all phobos containers, right? - At least if the prerequisites are met. The relevant prerequisite for this version of "remove" is "isForwardRange!Range" which is clearly the case for SList(T).Range. Nevertheless "remove" tries to access "popFrontN" and "popBack" which are not part of the ForwardRange specification. The lvalue-errors are another issue. I would clearly say this implementation of remove is buggy - or am I wrong? * The second call to remove does not succeed because there is no member function "remove". Instead there is "linearRemove". This is not a bug of course. But if I want to write code that uses some unspecific container it is very inconvenient that instead of "remove" I might have to call "linearRemove" or "stableRemove". Why not add a simple alias linearRemove remove ? This is sensible as "linearRemove" is a specialization of "remove". So the general function "remove" would always be present but the specialized function "linearRemove" or "stableRemove" would only be present if it makes sense for the specific container. Regards, enuhtac
Re: std.database design suggestion
Am 11.10.2011 05:14, schrieb Johann MacDonagh: Perhaps my design pattern knowledge is a bit shaky (it is), but isn't the point of a factory to give it hints about what you want to create, and it decides how to do it? Something like: Database d = Factory.gimmeAConnection("MySql", "server", "username", "pwd"); I guess you describe the "Factory method" pattern. def : Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. My snippet is based on the "Abstract Factory" pattern. Also called "Factory design" pattern or simply "Factory" pattern . Indeed a bit confusing. def : Provide an interface for creating families of related or dependent objects without specifying their concrete classes. see also > http://www.dofactory.com/Patterns/Patterns.aspx
Re: [std.database]
On 2011-10-11 05:08, Johann MacDonagh wrote: On 10/8/2011 2:43 AM, Steve Teale wrote: I use this title at Andrei's suggestion, and repeat his idea that it be used as a prefix for discussions as we navigate toward a design. Unless there is resistance to the idea, I will on the job of implementing whatever we decide is appropriate. I am retired, and have the time to do it. It seems that every man, and possibly his dog, has a private implementation for at least a favorite DB, so we should have plenty of material to build on. At this point I would like to get responses from those who feel they are likely to contribute to the design through to completion. I'd also like to get a feel for the magnitude of the task, so I'd like to ask what database systems you think should be supported. I have started a github account, and will put my mysqld stuff there shortly, then you can kick me out if you don't like what you see. Steve I've written up a prototype for a "LINQ" style database querying mechanism in D (read about "LINQ to SQL" if you've never heard of it). Legally speaking, it has very little to do with LINQ, but the concept is similar. Basically, it allows you to write code like this: auto x = new SqliteConnection("mydata.db"); foreach(y; x.MyTable.where("someField > 10")) { // y is a wrapper around Variant[string] with some opDispatch magic writeln(to!string(y.MyField)); writeln(to!int(y.SomeOtherField)); } Of course, "MyTable" is handled via opDispatch. The SqliteConnection doesn't care what tables are available in "mydata.db". You can also do much more. Such as: x.MyTable.startAt(20).limit(10).where("blah").select("somefield", "sometingElse"); In addition, you should be able to do something like this (don't think I've implemented this yet): x.MyTable.select!MyStruct(); Doing that would return a range of MyStruct structs, rather than the wrapper around Variant[string] like above. This would allow you to do: auto x = new SqliteConnection("mydata.db"); foreach(y; x.MyTable.where("someField > 10").select!MyStruct()) { // y is a wrapper around Variant[string] with some opDispatch magic writeln(y.MyField); // No more needing the to! template writeln(y.SomeOtherField); } Of course, this would allow you to find typos in field names at compile time (provided your struct is kept in sync with the database), and means you don't have to go through the Variant[string] for all your database accesses. To implement this, a database "driver" would have to have a shared opDispatch implementation (perhaps done with a mixin or maybe with an abstract class), and it would have to be able to translate the "query" into a SQL query that works with their underlying database system. I have a working prototype somewhere that works with Sqlite, and it seems to work very nicely. Clearly a system like this shows off what D can do out of the box (opDispatch), and makes writing scripts very easy. Let me know if this is something you think should be part of std.database (or whatever we end up calling it). I think that the use of opDispatch and selecting with a struct should be available at the higher level interfaces and not in the low level interface. -- /Jacob Carlborg
Re: Matrix-type-friendly syntax and more
Don: > That's true, IF you are happy to have it as a feature which can only be > used in user-defined types. If you want it apply to built-in arrays as > well, the effort is immense. This is not wonderful, but for me it's acceptable. Having that syntax support only for user defined types is quite better than having to use a syntax like stride(...) suggested by someone else. - For a simple but nice usage example of strides in Chapel language see pages 14-33 here: http://chapel.cray.com/tutorials/SC10/M10-8-Samples.pdf Strided grid description var cell_centers = [1..7 by 2, 1..5 by 2]; var vertical_edges = [0..8 by 2, 1..5 by 2]; var horizontal_edges = [1..7 by 2, 0..6 by 2]; var vertices = [0..8 by 2, 0..6 by 2]; (See the slides for more info.) Bye, bearophile
Re: Static arrays, typeof and IFTI?
Norbert Nemec: > However there does not seem to be any way to state > int[...whatever...] myvar = [1,2,3,4]; > enum N = typeof(myvar).init.length; > and let the compiler deduce that N==4. Since years some people (among them there is me too) are asking for this syntax: int arr[$] = [1,2,3,4]; Vote for it here (an enhancement request from 2006!): http://d.puremagic.com/issues/show_bug.cgi?id=481 Bye, bearophile
Re: Matrix-type-friendly syntax and more
On 10.10.2011 20:03, Norbert Nemec wrote: On 10.10.2011 07:34, Don wrote: On 10.10.2011 04:41, kenji hara wrote: 2011/10/10 bearophile: So is this: y[$-6, 0..$:2] Translated like this? y.opIndex(y.opDollar!0 - 6, y.opSlice!1(0, y.opDollar!1, 2)) I have no thought about it. I'm not sure that the additional stepping is really useful, but I think adding it into syntax is not impossible -- it might not conflict with associative array literal. Kenji Hara Personally, I think that since strided operations are so inefficient, they should remain ugly. Inefficient?! For multidimensional arrays, all but one dimension have non-trivial, runtime-dependent strides anyway. The problem is with built-in arrays. Anyway, the expressiveness gained by strides is significant and the effort to allow it in the language is minimal. That's true, IF you are happy to have it as a feature which can only be used in user-defined types. If you want it apply to built-in arrays as well, the effort is immense.