Archive

Archive for the ‘Ideas’ Category

What do you use for String localization in Delphi?

February 15th, 2012

Delphi an an ITE for localization (of which I’m not a fan), we’ve been using something very similar to gnu gettext where I work (and I like it), what other String or screen localization tools have you been using and recommending?

You can vote for multiple options, and suggest new ones in the comments!

What do you use for string localization in Delphi?

View Results

Loading ... Loading ...

Ideas

What do you think of function overloads?

January 26th, 2012

In Delphi, you can overload functions, but doing so requires using the overload directive explicitly, f.i. the following code declares two functions with the same name, one that will be invoked if you pass an integer, another that will be invoked you pass a string:

function MyFunc(a : Integer) : String; overload;
function MyFunc(s : String) : String; overload;

In many other languages, the overload directive is implicit, you don’t have to type it and you can always overload. On the other hand, it means that as long as your parameters differ, you can end up overloading an existing function without noticing, which can lead to confusion.

What do you think of function overloads?

  • They're confusing, they shouldn't be allowed. (3%, 11 Votes)
  • They can be useful, but should be explicit via a directive. (72%, 246 Votes)
  • They're very useful, no directive should be required. (25%, 85 Votes)

Total Voters: 342

Loading ... Loading ...

Ideas ,

Zero-based Strings indexes?

December 15th, 2011

In a now infamous and enormous thread I won’t name, Allen Bauer dropped a bomb:

<bomb>Oh, and strings may become immutable and 0-based ;-)…</bomb>

Currently Oxygene has zero-based strings, I was considering it for DWScript too, but the backward-compatibility implications are a bit too huge (yes, we and customers have many years of accumulated DWS code), and the kind of issues triggered by that are hard to track/fix/warn about… or are they?

One evolution that is looming (at least for DWS, can’t speak for Delphi) is having methods on base-types too, since these would be new methods, with no legacy, a zero-based convention could be introduced there, f.i.:

sub := Copy(str, 1, 10); // legacy, 1-based
sub := str.Copy(0, 10); // new, 0-based

As time passes, the functions would be marked as “deprecated”, and code migrated over to methods incrementally. The interim time would of course be a mess mix of zero and 1-based conventions… not very desirable, but certainly preferable to breaking code in non-obvious ways.

One hard case (without easy compiler-warnings) that would remain would be that of indexed character access, like “str[i]“. I can think of only one safe way around that one: not having a default array property. That could however be leverage to gain some, f.i.:

char16 := str.Char16[i]; // equivalent to old str[i]
code := str.Code16[i]; // equivalent to old Ord(str[i])
charStr := str.Char[i]; // new, retrieves the whole character (1 one or more char)
codePoint := str.Code[i]; // new, retrieves the whole unicode codepoint

The Xxx16 versions would return a a WordChar, equivalent to a current Char, and only capable of holding a character from the BMP. The Xxx version would return a String (a whole Unicode character/codepoint) or an UTF32 code.

Comments? Other Ideas?

Ideas , , ,

Taming the flock with Object Pascal

September 28th, 2011

And now for a more interactive demo than last time, this is a full-screen HTML5 Canvas interactive demo with the source in Object Pascal, compiled to JavaScript by the DWScript JS CodeGen. Click below to see it in action and hit F11.

Click-me, I'm best seen in action!

It illustrates using records, classes, and invoking the HTML5 Canvas and jQuery directly from Pascal code.

Chrome handles it best, but IE9 and FireFox are doing reasonably fine.

This time, I’ve wrapped it up in a demo zip (653 kB), where you can have a look at the DWScript code, the Delphi code required to compile & run the demo, and you can even fiddle with the source and over-simplified compiler options (Debug/Release/Obfuscated) with the included pre-compiled executable.

To compile the demo yourself, you’ll need DWScript (SVN version), SynEdit (SVN version) and Indy (the version included with Delphi XE should be okay), which is used for a mini-web server to allow running the demo directly in your favorite browser.

Ideas ,

How would you name TObject’s ancestor class?

June 23rd, 2011

I’m looking for a good name for a “TObject ancestor” class, that would introduce no Pascal baggage: no “Create”, no “Destroy”, no “Free”, etc.
TObject would become a subclass of that root class.

A good name would have to be meaningful as being the “true” root of the class hierarchy, and ideally, it would have to be a name unlikely to conflict with existing class names in existing code (so TRootObject, TBaseObject, etc. likely don’t cut it).

The underlying purpose would be to allow integrating everything in the class system, including objects defined in other languages, and seeing them as objects rather than interfaces (which have a baggage of their own), ie. allow them to have directly accessible fields, allow subclassing, etc.

Any good name ideas?

edit 06-24: Thanks! Quite a lot of comments and suggestions! ;-)

To clarify things a bit, the TDWSxxx suggestions are interesting, but semantically-speaking, a TObjet in DWS is an actual DWS object. Also the “ancestor of TObject” would be used to bring in f.i. Java objects, for which TObject methods like .Free or .ClassType f.i. either don’t have a meaning, or would have a different one. One way could be to make all TObject methods virtual and raise exceptions when they’re meaningless, but that would be a runtime solution to what is a compile-time problem.

All this might be a bit fuzzy, as it revolves around things brewing in the lab, and should become clearer in a few weeks time!

FWIW an ancestor of TObject could also be useful in Delphi for special purposes, and could serve as basis for non-reference-counted interfaces (f.i. if you were to introduce a garbage-collection in Delphi).

Ideas

Poll: dynamic arrays as reference or value type?

June 15th, 2011

Here is a small poll to help me decide in which direction to go about dynamic arrays in DWScript. The poll is at the bottom of the post, to encourage reading before voting ;-) .

The Problem

In Delphi, fixed-size arrays behave as value types, while dynamic arrays behave as reference type, this can be illustrated by:

type
   TFixedSizeArray = array [0..9] of Integer;
   TDynamicArray = array of Integer;
...
procedure SomeProc(fixed : TFixedSizeArray; dynamic : TDynamicArray);
begin
   fixed[0]:=2;
   dynamic[0]:=2;
end;
...
var
   f : TFixedSizeArray;
   d : TDynamicArray;
begin
   f[0]:=1;
   SetLength(d, 10);
   d[0]:=1;
   SomeProc(fixed, dynamic);
   // at this point f[0] is still 1, but d[0] is now 2
end;

However if you change SomeProc to

procedure SomeProc(fixed : TFixedSizeArray; dynamic : TDynamicArray);
begin
   fixed[0]:=2;
   SetLength(dynamic, 20);
   dynamic[0]:=2;
end;

then d[0] will be unchanged, as the SetLength() call will have spawned a different dynamic array, if you want to resize a dynamic array you have to pass it as a var parameter, while if you only want to change the items, you don’t…

With current Delphi syntax, dynamic arrays are schizophrenic: they are passed by reference, like a TObject would be, but resized as value types.

In a way, dynamic arrays borrow the String type’s SetLength() syntax and behavior, but String is passed in a form that mimics a value type, in the example above, it would behave like TFixedSizeArray, ie. if you modify a String that wasn’t passed as var in SomeProc(), the original variable won’t be changed.

The Options

To rationalize the situation, there are two options:

  • make dynamic arrays a value type, with similar copy-on-write optimization as String to minimize unnecessary copies. A side benefit is that it makes dynamic arrays behave similarly to fixed-size arrays, all would behave as value types, a downside is a performance hit on write accesses (for the copy-on-write mechanism).
  • make SetLength() treat dynamic arrays as a 1st-class reference type, ie. have it work as dynamic.SetLength() would, and if you need to make a unique copy of a dynamic array, you would use a dedicated function like Copy() rather than piggyback SetLength().

So, what would feel more natural to you?

Dynamic arrays would be better as...

  • a value type, like non-dynamic arrays, minimize the surprise factor (38%, 22 Votes)
  • a full self-respecting reference type, more practical and efficient (62%, 36 Votes)

Total Voters: 58

Loading ... Loading ...

Ideas

Poll: Templates or Generics?

April 15th, 2011

I’m wondering about this question in the context of scripting.

The poll itself is at the bottom, of this post, so you’re encouraged to read the arguments and relevant comments first ;-)

Templates

As a reminder, when using templates, the templated type is substituted upon template instantiation, meanings that anything you could write or perform with a “replace all” in the code, you can achieve with a template, for instance

type TMySum<T> =  class
   FSum : T;
   procedure Add(value : T);
end;

procedure TMySum.Add(value : T);
begin
   FSum := FSum + value;
end;

can be used, and will work if T is a type that supports the ‘+’ operator (a String, a Float, an Integer, or just about anything upon which ‘+’ was overloaded). So you get a form of duck-typing, which is both flexible and powerful.

The downside is that if for T you pass a type that doesn’t support the ‘+’ operator, you’ll get an error message, and when abusing making the most of the templates system, like C++ guys do, you can end up with fairly cryptic errors. Even nesting two templates can already lead to non-trivial errors.

Generics

Generics on the other hand are type-checked upon declaration, not upon instantiation, so if the code of a generic compiles, it’ll work. However, that requires specifying constraints, for instance in the form of interfaces the type you specialize upon should support.

The downside of generics is that even for basic stuff (such as addition) you need interfaces to constrain the type-checking, and code can get very convoluted as you end up having to implement a whole jungle ecosystem of interfaces once you step outside of collections and containers.

You also have to be “creative” from time to time to bypass the limitations, for instance, the source-code for a generic-version of the above TMySum<T> would have to be as creative as what you find in the RTL’s Generics.Defaults for the comparisons (have a look there yourself).

So, what would it be for you?

For *scripting* purposes, would you prefer...

  • Templates, expressiveness first, scripts can't get that complex anyway (42%, 40 Votes)
  • Generics, strictness first, scripts are complex enough as they are (58%, 55 Votes)

Total Voters: 95

Loading ... Loading ...

Ideas , ,

SamplingProfiler & Windows 7

January 15th, 2011

As you may be aware, for and unknown reason SamplingProfiler doesn’t work under Windows 7, the technical details as to what doesn’t work under Windows 7 are in this stackoverflow question:

GetThreadContext fails after a successful SuspendThread in Windows 7

If you’ve any idea of the answer, or know someone who might know the answer, any help would be appreciated! The documentation on the subject is very limited both on the Microsoft site and on the Internet…

edit: following a suggestion by Dan Bartlett on stackoverflow, it seems the issue was an alignment constraint introduced (or enforced?) in Win! I’ve compiled a beta version with the change, grab it here: SamplingProfiler-win7-beta.zip (679 kB), if fix is confirmed, I’ll make a full release. A full release is now available.

Ideas

Generalized class-helpers/pseudo-objects?

December 23rd, 2010

I’ve been toying with the idea of generalized “pseudo-object syntax”, which would essentially be a form of syntax sugar.
It would allow passing the first parameter of a function call with the method syntax, f.i.

i.IntToStr();
i.Inc( 2 );

would be understood as being just a syntaxical variation of

IntToStr( i );
Inc(i, 2);

Essentially, every class-less  function/procedure could become a generalized class helper, that could operate on just about any type. Additionnally (or declaratively) you could also use a variation of the declaration f.i.

function Integer.IntToString() : String

could be equivalent to

function IntToString( Self : Integer ) : String

Of course there are some visibility issues to decided on, f.i. if I have a myClass.ToString method, would it take precedence over a ToString(myClass) function (I would say it should)? and whether such an extensibility would be implicit or declarative?
Do you know any language that implements such an approach?

Ideas