views:

436

answers:

14

I have been looking at the differences between Lucene 2.9 particular the redone tokenstream API and it just occurs to me its particularly ugly compared to the old just return a new or repopulate the given with values if your reusing said Token.

I have not done any profiling but it seems using a MAP to store attributes is not that efficient and it would be easier to just create a new value type holding values etc. The TokenStream and Attribute stuff looks like object pooling which is pretty much never necessary these days for simple value types like a Token of text.

A: 

well, it was a well-known library about 20 years ago, but i think the original btrieve data engine has the worst api ever written. almost everything goes through a single call, with each of its many parameters containing a different value depending on which call you're really doing (one parameter was a flag telling the system if you wanted to open a file, close a file, search, insert, etc). i liked btrieve way back then, but i spent a long time making a good abstraction layer.

it could have been easily improved by not forcing everything into one call. not only was the one call hideous, but the programmer was responsible for allocating, passing in, and freeing the position block ... some memory used by btrieve to track the open file handle, position, etc. another improvement would be to allow ascii text to be used when defining the indexing. indices had to be specified by a convoluted binary representation.

best regards, don

Don Dickinson
Sounds similar to old dos int calls where many functions were accessed by a common int and only differentiated by a number in s register.
mP
that would be what it was modeled after i think. just the fact that the engine is too lazy to allocate its own memory for the control block drives me nuts.
Don Dickinson
+1  A: 

Most certainly not the ugliest. There are probably so many, but Flex has a special place in hell. Specifically UIComponent which compared to the Sprite, feels like using a chainsaw to peel an apple. I believe Flex would have been much improved by using more lightweight objects and mixin-style features similar to how Dojo works on the Javascript side.

The ECMAScript/Actionscript Date class is all but backwards and useless. It's been a constant pain any time I've needed to do something more complex than add timestamps to logs. They need more parsing options (e.g., the ability to specify the input format), and better time management, like intelligent increments, convenience functions, etc...

C++ STL libraries (and templates in general), while obviously useful, have always felt plain ugly. No suggestions for improvements though. They work.

Glenn
+2  A: 

Certain java.io.File methods, critical to systems programming, return a boolean to indicate success or failure. If such a method (like, say, mkdir or delete) fails, you have no way at all to find out why.

This always leaves my jaw a-hangin' open.

Jonathan Feinberg
Yup an extremely ugly non oo wrapper over some c code.
mP
+5  A: 

I've never been a fan of the java.sql package...

  1. You have to catch the checked exception for everything, and there's only one exception, so it doesn't really give any indication of what went wrong without examining the SQL code String.
  2. Add to that the fact that you have to use java.sql.Date instead of java.util.Data, so you always have to specify the full package for one or the other. Not to mention the conversion that has to take place between the two.
  3. And then there's the parameter index, which is 1-base-indexed instead of the rest of Java, which is 0-base-indexed.

All in all, a pretty annoying library. Thankfully, the Spring library does make it quite a bit easier to work with.

Kaleb Brasee
I hate the single SQLException. Duplicate key, SQL syntax, they come back to my code the same way.
MBCook
A: 

A lot of the CRT library functions are poorly or vaguely named possibly due to legacy coding restrictions back in the day and thus require frequent use of the F1 key for people to find the right function and supply the right arguments.

I've been using CRT functions for a while and I still find myself hitting F1 a fair amount.

Nick Bedford
+3  A: 

COM. Its biggest improvements ended up being .NET.

280Z28
I haven't used COM myself, buy I've *looked* at it. IIDIIInterface nightmare!
Nick Bedford
COM was great in the day when visual studio 6 was new. The major ugliness of COM comes from its varies wrappers, like ATL which use excessive hungarian notations..NET is fully COM compliant.
Andrew Keith
i think COM is so awful because EITHER 1) microsoft wanted it that complicated so it tied you into using their compilers. it took a long time for anyone outside of microsoft to implement COM without an MS compiler OR 2) the eggheads at microsoft got one too many phd's and didn't care about making something people could actually use without a microsoft compiler
Don Dickinson
+6  A: 

creat()

When Ken Thompson and Dennis Ritchie received the 1983 Turing Award, after their respective acceptance speeches, someone in the audience asked Ken what he would do differently with Unix if he were to do it all over again. He said, "I'd spell 'creat' with an 'e'."

Vlagged
I want to say "LOL", but that doesn't have 15 characters.
Jonathan Feinberg
I'm not sure about ugly, but I'll give an upvote for the funny quotation.
Ben Alpert
it has been fixed: http://code.google.com/p/go/source/detail?r=4a3f6bbb5f0c6021279ccb3c23558b3c480d995f
Vlagged
I picked this because it had the most votes. There are plenty of other worthy answers but its hard to pick the "best"...
mP
+1  A: 

I would say MFC, ATL and WTL. All 3 of these libraries use excessive hungarian notation, redefine data types for no apparent reason (CString redefined over and over) and are notoriously changed with each version of visual studio.

I like COM. It provides a component oriented architecture long before .NET was even developed. However, the expansion of COM into DCOM, its many wrappers like ATL and its general lack of comprehensive documentation make it the ugliest API i have to deal with at work.

Andrew Keith
+3  A: 

Java's date/time API is pretty horrible to work with. java.util.Date has several constructors to create an instance for a specific date, but all of them are deprecated. java.util.GregorianCalendar should be used instead, but that has an extremely annoying way of setting fields (think calendar.setField(GregorianCalendar.MONTH, 7) instead of calendar.setMonth(7) which would be far better). The finishing touch is that most other classes and libraries still expect a Date instead of a Calendar, so you have to constantly convert back and forth.

Kees Kist
While dates/times appear all over the place in ones code, if you ignore the deprecated methods and make defensive copies and ignore the weird type heirarchy it's not a major headache. If you ignore defensive copies and start poking around using deprecated Apis your asking for trouble. But date time etc are just a few value types they are not functionally rich like a big library like the one ice used in myexample. Working around nasty date is one a few lines at a time but Lucene attributes in tokenstreams will be a bit more involved.
mP
+2  A: 

Not not a winner, but deserves a honourably mention; Android. Uses the Java 5 programming language, but barely any of the Java 5 language features. Instead of enums you get integer constants with prefix or suffix.

It can not quite decide if it should be object oriented, or procedural. Showing dialogs being a prime example. Several callbacks with self defined integer ids to display call upon the dialog, that smells of an old C API. And then you get an inner builder class class with chained methods, that smells of over architectured OOP of the worst kind.

The MotionEvent class have X and Y coordinates as absolute and relative values from the same accessory method. But no way to check what kind of coordinates it currently holds.

Android sure is a mixed bag.

PeyloW
Android prolly uses ints rather than enums because enums are classes and eat a bit of more memory.
mP
Yes that is true, and that is the official stance. But I find it as stupid as "No one needs more than 640K RAM". When building a "modern" framework, you should plan for the future, not let the past force you into a bad design. It is not like an enum takes THAT much memory.
PeyloW
What's more, there's nothing preventing a compiler from turning enums into ints.
Jonathan Feinberg
Premature optimisations the bane of the "other" programmer.
mP
@mP: And yourself. Never write code today, that you can not debug tomorrow. Optimizing tight loops is often a waste of time, change the algorithm instead.
PeyloW
Yup thar and the cut copy paste key.
mP
Most code smells can be traced back to some one just finishing up and getting the he'll outta there without thinking they are damning the next person including themselves to hell. After all if you produce crap and so does your mate and his mate next door the smell will eventually float back after all the codebase is a closed system.
mP
Android, and in particular Dalvik, reeks of trying to hack a JVM into doing something (interacting at a lower level with the system) it wasn't originally targeted for. The could have chosen the CLI and had this type of performance automatically, or they could have spent time writing a *real* JIT targeting the device. In this case, their anti-Microsoft bias just left everyone with an OS lacking FAR behind what it would be capable of.
280Z28
Why would the CLI be any better? The biggest difference between Dalvik and JVM is register vs stack based. The CLR is not that different from the JVM and is also stack based.
mP
+2  A: 

I'm going to turn this question on its head and name a beautiful API for a library whose standard API is mostly ugly: the Haskell bindings for OpenGL.

These are the reasons:

  • Instead of lumping everything into a small number of headers, the library is organized logically into discrete modules, whose contents parallel the structure of the OpenGL specification. This makes browsing the documentation a pleasant experience.

  • Pairs of "begin/end" functions are replaced by higher-order procedures. For example, instead of

    pushMatrix();
      doSomeStuff();
      doSomeMoreStuff();
    popMatrix();
    

    you'd say

    preservingMatrix $ do
        doSomeStuff
        doSomeMoreStuff
    

    The syntax of the bindings enforces the conventions of the library, instead of making you do it by hand. This works for the drawing primitives of quads, triangles, lines, etc. as well. All of this is exception-safe, of course.

  • Getters and setters are replaced by idiomatic "StateVars", making reading and writing a more symmetric operation.

  • Multiple versions of functions replaced by polymorphism and extra datatypes. Instead of calling, say, glVertex2f with two float values, you call vertex with a value of type Vertex2 GLFloat.

References:

jleedev
OpenGL in Haskell is really nice, but the main reason that normal OpenGL is so ugly is that C is ugly. It's hard to design a really nice C API.
Zifre
@Zirfe - You and I disagree on what is ugly. It is quite possible to design a nice C API. It's just rather challenging.
Chris Lutz
+1  A: 

Livelink (OpenText) API

  • Everything comes back as some bizarre form of a jagged array
  • The documentation provides absolutely no examples
  • [your favorite search engine] typically returns no results for a given API method
  • The support forums feel near abandoned
  • The only reliable way of understanding the resultant data is to run the data in the Livelink debugger
  • And finally... the system costs tens (hundreds) of thousands of dollars

The wall next to my desk has an imprint of my head...

A very simple example of getting a value out of an API method:

var workflow = new LAPI_Workflow(CurrentSession);

// every Livelink method uses an out variable
LLValue outValue;
// every method returns an integer that says if the call was
// a success or not, where 0 = success and any other integer
// is a failure... oh yeah, there is no reference to what any
// of the failure values mean, you have to create your own
// error dictionary.
int result = workflow.ListWorkTasks(workId, subWorkId, taskId, outValue);


if (result = 0)
{
  // and now let's traverse through at least 3 different arrays!
  string taskName = outValue.toValue(0).toValue("TASKS").toValue(0).toString("TaskName");
}

Aaack!!! :D

Metro Smurf
+2  A: 

Direct3D!

No doubt the old pre-Direct3D 5 interface was pretty darn fugly:

// GL code
glBegin (GL_TRIANGLES);  
  glVertex (0,0,0);  
  glVertex (1,1,0);  
  glVertex (2,0,0);  
glEnd (); 

// D3D code, tonnes of crap removed
v = &buffer.vertexes[0];  
v->x = 0; v->y = 0; v->z = 0;  
v++;  
v->x = 1; v->y = 1; v->z = 0;  
v++;  
v->x = 2; v->y = 0; v->z = 0;  
c = &buffer.commands;  
c->operation = DRAW_TRIANGLE;  
c->vertexes[0] = 0;  
c->vertexes[1] = 1;  
c->vertexes[2] = 2;  
IssueExecuteBuffer (buffer);

Its not too bad, nowadays - it only took Microsoft 10 versions to get it right...

Justicle
A: 

Oracle's Pro*C, Pro*Ada, Pro*this-that-the-other things. They were a preprocessor front end for C, Ada, and Fortran, I think, maybe some others, that let you jam SQL into your source code.

They did also have a library which worked much better, and was much more flexible.

(That was more than 10 years ago, I have no idea what they do now, though I wouldn't be surprised if it was still the same, just so as not to break people's code.)

smcameron