Which is exactly what you should do indeed - but if the author did that from the start he wouldn't had any of these issues. If you use decimals in the database and doubles in code, you're just asking for huge trouble as conversion between the two is lossy. Silly blog author is silly.

Java doesn't have an IEEE decimal class, or any fixed size decimal class, just BigDecimal which a) has only been usable since java 5 and b) has a reputation for being slow as a dog. And the MySQL documentation doesn't clearly flag the issue:http://dev.mysql.com/doc/refman/5.0/en/ ... sions.html

So I even though you're right it's easy to see how he made the mistake he did.

Well, that page does list BigDecimal as the "native" type when you just call getColumnClassName/getObject on the column, but true, it's an easy mistake to make. I just got lucky I guess that I saw it the first time, I've always either worked in cents (64-bit long) or BigDecimal with money, floats are just evil for that. Mostly longs, because of

Quote:

As of MySQL 5.0.3, DECIMAL values are stored in binary format. Previously, they were stored as strings, with one character used for each digit of the value, the decimal point (if the scale is greater than 0), and the “-” sign (for negative numbers).

Number as varchar, yeah, no thanks.

But as for BigDecimal being new, enterprise software does lag a bit behind, SE 1.5 @ Sep 2004 -> EE 1.5 @ May 2006, but I certainly hope that any new code targets at least 1.5 nowadays, 1.5's generics is one of the must have features of Java, I can't go back to casting every list.get() from Object.

Holy shit. I never thought I'd see Math.random() in "production grade" code. This is awesome

Showed that to a coworker, and he said (jokingly) that he was going to go suggest that we use it for one of our projects (which has become somewhat notorious for being something of a mess).

Then he went and looked... turns out we already were using MongoDB as part of said project. No word on whether or not we're using those particular Java bindings, but if that code's representative of the quality of the project as a whole...

I'm pushing myself to futz with Java. I must be doing something stupid (yes, besides working with Java). I have two JAR files, main one at /var/app/main_app.jar. I have a library at /usr/share/java/library.jar that I need to include. Previously, the programmer did it by copying library.jar into the jre/lib/ext directory, I want to try to do it using the classpath switch on the command line. Here's the problem:

I'm pushing myself to futz with Java. I must be doing something stupid (yes, besides working with Java). I have two JAR files, main one at /var/app/main_app.jar. I have a library at /usr/share/java/library.jar that I need to include. Previously, the programmer did it by copying library.jar into the jre/lib/ext directory, I want to try to do it using the classpath switch on the command line. Here's the problem:

Yikes, glad I've never needed MySQL for anything more serious than Wordpress.

Reminds me of a former coworker insisting we use char(8) to store dates. "Just input YYYYMMDD so operators work like normal". What could possibly go wrong?

Lucky you. I had some MySQL/PHP projects that had to be fixed at previous jobs. Adding STRAIGHT JOIN everywhere to get queries to run fast enough is a major pain, and running myisamchk when strange stuff happens and praying nothing critical was affected.

But nowadays MariaDB with InnoDB seems quite decent, I might try it on a new project as PostgreSQL is insanely heavy on writes and disk usage if you use it as tuple store, the per row and per index overhead is insane.

I have a variant of that from the ages when timestamp with timezone is still a bit messy to work with - bigint millis since epoch instead of SQL datetime type. It works okay, but any operator other than straight eq, lt(e), gt(e) is messy. Oh well, it's fast, portable, and if you use only UTC in an app it's less work than datetime with timezone.

I'm pushing myself to futz with Java. I must be doing something stupid (yes, besides working with Java). I have two JAR files, main one at /var/app/main_app.jar. I have a library at /usr/share/java/library.jar that I need to include. Previously, the programmer did it by copying library.jar into the jre/lib/ext directory, I want to try to do it using the classpath switch on the command line. Here's the problem:

Why are you so complicated? All I'm trying to do is write a extension (based on the supplied SQL extension, with additional behaviour that our installations need) and you refuse to work properly. My custom table is in the object file that "light" compiles but not in the resulting MSI. I know it has rows in it because I added a load of message boxes to the code which are displayed when I compile my MSI project. What gives?

What's the benefit of the shade plugin over a jar-with-dependencies built by the assembly plugin?

The shade plugin is a fair bit more powerful and configurable; it'll let you do things like exclude dependencies (for components that are only build-time or test-time dependencies, like Junit), relocate packages, and transform resources. Jar-with-dependencies is basically an all-or-nothing affair.

Why are you so complicated? All I'm trying to do is write a extension (based on the supplied SQL extension, with additional behaviour that our installations need) and you refuse to work properly. My custom table is in the object file that "light" compiles but not in the resulting MSI. I know it has rows in it because I added a load of message boxes to the code which are displayed when I compile my MSI project. What gives?

My reason for my foray into Java is of course looking at an existing project at work. I'm looking at how it was setup and what I can do to make it righter as this was done by the same programmer as some of the PHP WTFery I've been posting in here.

The Java is no better. It's a syncing app that matches the data from the main database application to the home grown PHP web app's MySQL backend. For some reason, there are hundreds and hundreds of generated queries run through the database that look like this:

Code:

SELECT col_a FROM table_1 WHERE col_a = id_val

So yes, it selects a value from a table if the value is already known. Strangely, the only code that leads to this query being generated and run is after already pulling the value from the table...I'm having trouble wrapping my brain around this. I feel like they went overboard complicating this and forgot what it does. Does anyone else do that?

In my learning of F# I have started to really appreciate non-null by default type systems, and can see why people argue this should be default.

However after thinking about it some, it seems like you can't have a type system that's not null by default and the concept of constructors with parameters at the same time. If you have a type that only has a constructor that takes a parameter (for example, a class that wraps some operations for a TCPSocket) there's no way to instantiate an array of X length of that class, which is impossible without creating invalid objects.

Go (which I don't believe is non-null by default) doesn't have constructors, and it sucks because you can't assume that everyone will create your object by correctly calling the New* method. F#, since it's .net, allows you to create types that don't have a default () constructor, but those are just classes which then can be null. Not sure what Scala does, but I would assume it's the same as F# since it's based on the JVM (I could be wrong though).

I'm not necessarily saying that parameterized constructors are worth having null by default tests, but it seems like it can cause some complications and having to manually verify that your object was correctly created has to happen in multiple spots instead of just one. So it seems like it's not as straight forward of a decision as it seems to be argued out on the internet for.

It also seems to me (though I'm probably wrong) that non-null by default type systems are primarily prevalent in functional languages, and are not done in imperative languages. Go could have probably easily gone non-nil by default since they don't have constructors, but who knows why they chose not to.

Functional languages usually emphasize laziness and immutability. A pattern like "instantiate a Socket array, then call the individual constructors / setup methods later" is pretty standard in imperative programming, but would be a code smell in F#, imo.

Object constructors are that way because just about the only reason to really have a (non static) class is because you have state with invariants that the methods guarantee, and the constructor is just a method (with some complex compiler rules, but a method nonetheless) that ensures that's true from the get go.

Even for a POCO this holds true if the class is designed to be immutable, the constructor is simply maintaining the invariant that, post construction[1] the outside world will only ever see the object in that form.

Since f# values interop with other .Net highly, and has no issues with someone using mutability if they so desire, it just uses .Net arrays.

The 'create an array' aspect in f# is inherently therefore going to make you sacrifice immutability in some way[2] unless it stops you treating .Net arrays as such, forcing the construction of them on the basis of ensuring their state, when you can just mutate them straight after seems a bit pointless. What many simple[3] functional languages which value immutability supply for linear data structures instead is either linked lists, or things that look like arrays w.r.t random indexed access, but any attempt to modify one in fact creates a whole new array, with that modification applied. Given f#'s decision to use .Net arrays it is better (IMO) to keep the mutability a facet of the array, rather than force any types you want to use within an array to sacrifice immutability (or some other invariant).

One could of course define a language which specified that, on constructing an array, you were obliged to supply code to 'fill in' all of the elements, and only made the array available to you once that code had run, it could then not be modified further (Haskell has such functionality). You can layer such a thing in f# with a library (if it wants to be fast it will likely need to *use* a mutable array behind the scenes) however, that's not how much of the world MS is targeting with f# works if they are trying to use arrays, so why bother not allowing their 'direct' use in a language where you're already okay with people mutating state (even if you try to make it easy to not do so).

As far as non null by default goes, in f# Options can apply to any type, so you can declare an array of them instead. Then you make the 'not defined yet' part something the type system enforces, rather than an ever present hidden pit. That to me is the benefit of non null by default, forcing you to pay for allowing nulls (and giving you compiler help), but only where you need to.

This is, incidentally, not saying f# is better. Just a postulate as to why it's done that way (and why I'm glad it is, for my needs).

I guess my real question is, how would a non-nullable by default type system work in an imperative language? Would the sacrifice of parameterized constructors be worth very stringent use of nulls?

Also, how do you handle arrays of abstract types (i.e. interfaces, abstract classes, etc.)? Since they're not directly constructable at all, you'll run into the same problem.

Such a language would probably need to do one of two things to its arrays:

(1) Mandate that arrays which are of a type without a default constructor be nullable (essentially, Socket[] blah = new Socket[20]; is a compile error if Socket has no default constructor).(2) Provide for a default initialization of all elements at construction time (simplest case would initialize all elements the same, but one could envision a syntax that would allow for iteration and differences between elements, too).

Would the sacrifice of parameterized constructors be worth very stringent use of nulls?

Who needs to sacrifice them.

You either use arrays of type option<t> (or whatever your maybe monad is being called), or force the provision of code (lambda, callback, inline take your pick) that will run over every entry before the array is given back to you.

You can redesign the language as needed to suit the constraints you wish to apply.

If you added some other more complex types (such as integers which are always between 5 and 10, where one assumes that the 5 and 10 are 'generic') then creating an array of them would again require that you either: wrap them in the maybe monad, or provide legal initialisation code...

Why are you so complicated? All I'm trying to do is write a extension (based on the supplied SQL extension, with additional behaviour that our installations need) and you refuse to work properly. My custom table is in the object file that "light" compiles but not in the resulting MSI. I know it has rows in it because I added a load of message boxes to the code which are displayed when I compile my MSI project. What gives?

Yours in frustrationWM

There's a reason RobMen has his own consulting company now

I gave up trying to write an extension and declaring a bunch of custom tables in one of the files in my project. They show up in the resulting MSI and I can query them from a C# custom action and iterate through their data. Now I'm having problems getting connections to SQL Server using System.Data.SqlClient. It works if I hard-code a connection string but if I use values from my MSI's properties (server name, database name, etc), it tells me it can't find the server. Sigh.

WiX is extraordinarily powerful, but the documentation is awful and the moment that you want to do something like write an extension, you're on your own. I'm going to persevere with it, as it's so much better than our current (home grown) installer. It just might take a while.

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

I managed to solve my WiX problem. It was annoying me, so I rebooted into Windows after dinner and had a go at trying to recreate it. Which I did. The problem arose due to me using values like [SQLDATABASENAME] in my custom tables which refer to properties within the MSI. I was extracting these and using these in the connection string without formatting them to convert the syntax into real values like "MyDatabase". The reason why I thought I didn't have to do this is because the method that writes logging information for the installation does expand the MSI syntax to the real values.

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

Are you sure he's not converting from classic ASP to PHP? (Which is of course, TRWTF)

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

Are you sure he's not converting from classic ASP to PHP? (Which is of course, TRWTF)

Since it sounds like he's the one that wrote the original site I'd guess he is.

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

Are you sure he's not converting from classic ASP to PHP? (Which is of course, TRWTF)

Since it sounds like he's the one that wrote the original site I'd guess he is.

Ah. If that's the case, I'm still not seeing it in his OP, but that would make the whole story make more sense.

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

Are you sure he's not converting from classic ASP to PHP? (Which is of course, TRWTF)

Since it sounds like he's the one that wrote the original site I'd guess he is.

However after thinking about it some, it seems like you can't have a type system that's not null by default and the concept of constructors with parameters at the same time. If you have a type that only has a constructor that takes a parameter (for example, a class that wraps some operations for a TCPSocket) there's no way to instantiate an array of X length of that class, which is impossible without creating invalid objects.

You could have non-null-by-default with paramaterized construction; the inability to create an array like that isn't a problem for three reasons. First, it only matters if you actually try to create such an array. Secondly, if arrays can be initialized then you can create an array of such objects as long as you initialize it. Thirdly, you can have an array type that knows what elements are valid.

A company I built a pretty successful ecommerce site for last year was coaxed into doing a rewrite by another competing firm (to me). I won't get into the details, but sadly if it isn't broke, don't fix it applies here. I've heard whispers the project has gone from an estimated 4 month timeframe to 8-12 months because the developer is having a difficult time converting the code base from asp.net to php. He explained that because ".net is a dying language" the project is taking much longer than anticipated.

Are you sure he's not converting from classic ASP to PHP? (Which is of course, TRWTF)

Since it sounds like he's the one that wrote the original site I'd guess he is.

Is it bad that I thought "I would've just written in an algorithm that linearly decreases the amount of time it waits to make a save every day, meaning that I wouldn't even have to 'put in' the improvements"?

So even John Carmack confuses strong typing with static typing. This just goes to show... something.

Strong Typing is a wish washy term, there is no universally agreed on definition, and many competing ones. It's also a loaded term (strong > weak) so people tend to ascribe strength to whatever their own preconceptions indicate is "good" wrt typing. I've been guilty of this in the past.

Type systems are varied and complicated, I doubt there's many people who actually understand much of the nuances to have a decent discussion on it[1].

Nonetheless I very much think that static typing by default is incredibly useful at reducing bugs in a lot of software, my own included, especially when attempting to introduce change. In comparison I've found doing things in perl in that regard horribly painful. But that's deciding it on the basis of perl, not dynamic typing in general.

1. And I'm not one of them, though several others here certainly could.