May 13, 2011
"Jacob Carlborg" <doob@me.com> wrote in message news:iqilmh$7tk$1@digitalmars.com...
> On 2011-05-12 16:45, Adam Ruppe wrote:
>>> Could you share how or show an URL that provide sample code to do that in D?
>>
>> Check out my D api demo:
>>
>> http://arsdnet.net/cgi-bin/apidemo/
>>
>> Here's the source code (about 50 lines of D)
>> http://arsdnet.net/apidemo.d
>>
>> And the HTML templates it uses: http://arsdnet.net/apidemo-document.html http://arsdnet.net/apidemo-javascript.html
>>
>>
>> The libraries it imports are available here
>>
>> http://arsdnet.net/dcode/
>
> How is it working out with a static type system, compared to a dynamic, for web development?
>

<bias amount="very-large" inflammatory="potentially">
Much better I would imagine, since dynamic type systems suck &donkeyballs;.
</bias>


May 13, 2011
On 13/05/2011 08:09, Jacob Carlborg wrote:
> On 2011-05-12 16:45, Adam Ruppe wrote:
>>> Could you share how or show an URL that provide sample code to do
>>> that in D?
>>
>> Check out my D api demo:
>>
>> http://arsdnet.net/cgi-bin/apidemo/
>>
>> Here's the source code (about 50 lines of D)
>> http://arsdnet.net/apidemo.d
>>
>> And the HTML templates it uses:
>> http://arsdnet.net/apidemo-document.html
>> http://arsdnet.net/apidemo-javascript.html
>>
>>
>> The libraries it imports are available here
>>
>> http://arsdnet.net/dcode/
>
> How is it working out with a static type system, compared to a dynamic,
> for web development?

How many times, while using a dynamically typed language, do you ever change the type of a variable? I've written a fair amount of PHP, and I rarely, if ever want my string to suddenly become an integer (if I do it generally needs validation/conversion anyway). When using my own and others code I frequently see type checks/conversions etc, it just makes the code ugly - with a staticly typed system you remove this overhead.

Also, there's the auto keyword, and easily accessible function templates.

-- 
Robert
http://octarineparrot.com/
May 13, 2011
Jacob Carlborg wrote:
> How is it working out with a static type system, compared to a dynamic, for web development?

It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence.

I can't tell you how many times I've made a minor mistake in PHP, Ruby, or Visual Basic and had it slip through to production because the code path was obscure enough to evade testing.

Sometimes, something similar does happen in D - to!int("") throws - but, the compiler catches the majority of incompatible changes instantly.

If I had int addUser() and change it to User addUser(), I don't
have to hunt every instance down myself. Just hit compile and
the compiler tells me where the change causes problems. (Rarer than
you might think - thanks to auto, a lot of the program is already
duck typed in a way. The actual return value name is rarely used.)


It also helps documentation to have good types. I often see stuff like this in dynamic language docs:

function doSomething(options);

What does it return? What options are available? Maybe the text will tell us that options is an associative array. UGH, I hate that! Now, there's even less knowing what's going on.

D's documentation is a lot more helpful, and easier to keep up to date.

string doSomething(Options options); // not much better yet....

struct Options;
int speed;
bool strictMode;
bool caseSensitive;


Ahhh, now I know!





Another thing that the static types enable that I don't think is possible with dynamic functions is the automatic forms you see on my link.

http://arsdnet.net/cgi-bin/apidemo/get-a-box

I didn't write any html for that. The library made it for me.

In the source, you can see it's prototype:
http://arsdnet.net/apidemo.d
	Element getABox(Color color);


The reflection was able to say "it needs a Color, and there's only a handful of valid Colors - enum Color - so I can automatically create a <select> box for this."

Dynamic types for return values can still do most the stuff my api generator does. Whether it's a static function/template toHtml or a dynamic property doesn't matter much.

But the parameters... I don't think it can be done without the static types there.

(Another nice thing is the library checks the type too. Coming off the request parameters, you have strings; dynamic types. But going into the function, it knows it must be a Color, so it checks. If not, an exception is thrown.

By the time you're inside the function, you can be guaranteed that Color color is indeed a Color. Thus, to!string() to insert it into the html attribute that I did here is perfectly safe. It's a whitelist based filter, all done automatically.)



There are a few cases where dynamic types are helpful or needed. D lets us opt in to them with only a minimal amount of fuss.

The places where I use it are:

1) Data from the user. Form variables are of type string coming into the program. Once decoded, you have string[][string]. Your program probably wants something else.

The to!() template in Phobos makes this pretty easy, or if you
want default value and get/post combined, my cgi class has a request
template:

int a = cgi.request!int("a");

That's similar to this in PHP:

$a = 0;
if(isset($_POST['a']))
  $a = (int) $_POST['a'];
else
if(isset($_GET['a']))
  $a = (int) $_GET['a'];


PHP is so outrageously verbose. And the PHP is buggy compared to the D... if you do cgi.request!int("a", 10) and the user does a=txt, the PHP result is wrong. It's not quite fair to compare a function to a code collection though. A php function could do it right too.



Annnnyway, I'm digressing. Hell, I'm going on about weak types instead of dynamic types! Even in Ruby, you'd have to do a to_i since the url value simply is a string.



Back to dynamic types. The three other places where you see them are databases and interfacing with external services.

2) Databases

With databases, you probably expect a certain type anyway. If the column is typed as INTEGER, you probably don't want 'lol' in there. But, the database takes care of that for you.


In my libs, I just use strings.

auto line = mysql.query("SELECT id FROM users WHERE id = 10").front;

res[0] == "10"


Conversions are now done the same as URL parameters:

int id = to!int(res[0]);


Oftentimes, I don't really care about it though; if I'm outputting it to html, I'll just say:

table.appendRow(res["id"], res["name"])

and the like anyway. You want a string there, so it just works. (appendRow is in fact a variadic template so it'd just work regardless, but you get the idea anyway).


Thanks to static checks though, if I were to later change my mind and wanted ints, or made the database return Variants or whatever, no problem - the compiler will point out trouble spots to me.


Inserting data is the same:

mysql.query("INSERT INTO users (id) VALUES (?)", 10); // works
mysql.query("INSERT INTO users (id) VALUES (?)", cgi.post["id"]); // works too


Or using the data object class:

auto obj = new DataObject(mysql, "users");

obj.id = 10; // works
obj.id = "10"; // works just as well

obj.commitChanges();

(The DataObject can read too, offering database fields as obj.id style properties. They always return string, just like plain query, but are also read/write.)


DataObject can also be specialized automatically to use static types if you like.

db.sql:
create table users(id integer primary key, name varchar(30));

file.d:

// parse out that create table to map the names and types automatically
alias DataObjectFromSqlCreateTable!(import("db.sql"), "users") User;

User a;

a.id = "12"; // type mismatch, fails to compile
a.name = "hello"; // works
a.nmae = "sad" // typo caught at compile time

a.commitChanges(); // otherwise it is still based on DataObject



In short, I have the best of both worlds, with the only extra effort being writing to!() here and there and that one line to import the sql definition.


3) HTML

I *want* strict typing when working with html in almost all cases. It helps catch encoding bugs.

The one place where I want dynamics - fetching an element off
the html template - I have it, this time provided through classes.

auto table = cast(Table) document.getElementById("data-table");
assert(table !is null); // fails if it isn't a <table> tag

// use the table class's special functions


Forms, Links, and other types of nodes are handled similarly. The Element base class though does most the simple operations. Being plain old inheritance, the virtual functions act dynamically enough.

Of course, if the HTML changes, that assert/enforce will trigger at run time. We're still ahead of dynamic languages though: the compiler will tell me what breaks if I remove the cast, with one exception: I use an opDispatch there for attributes. That will break some functions.

Table t = ...;

t.caption = "Hello!"; // changes the <caption> tag child

Element t = ...;

t.caption = "Hello!"; // sets a caption="" attribute


But meh, in this case, I like the flexibility of accessing attributes like that. The compiler still catches more than it doesn't - we're still ahead of the mistakes possible in dynamic languages while keeping the convenience.


4) External services


This is where dynamic types are the most useful. Accessing Facebook,
Twitter, etc., returns xml or json with types that change based
on a lot of things. Is the user logged in? What url is it?

In this case, it's like the database, but the types tend to be more complex. Simple string cowboying won't cut it.

Thankfully, D's Variant is up to the task.


Variant userRet = fbGraph(token, "/me");

// we know /me returns a json object from the docs, so fetch it:

auto user = userRet.get(Variant[string]);

auto name = user["name"].get!string;

// name is a string == "Adam D. Ruppe"


Not terribly hard. Robert Jacques IIRC has written an improved std.json patch to make this work almost just like Javascript:

auto user = fbGraph(token, "/me");

user.name.get!string; // same as above


So D's definitely up to the job. The only difference is that final use of get!string. I believe Phobos' to! works as well.



In the end, there's nothing web related in my experience that a dynamic language can do that D can't do almost or just as well, and plenty that D and it's static types can do that dynamic types can't do, or require piles of painful tests and manually written code or documentation to do.


D kicks the Web's ass. (And my web related libraries go even further
than seen here. My custom DOM offers a lot of things that are way
cool, enabling new CSS stuff, filling forms easily, in about 1/10
the code of doing it similarly in PHP, and without mucking up the
HTML. The web api/site generator makes D accessible through urls,
forms, javascript - view the source here for a glimpse of that
lib:
http://arsdnet.net/cgi-bin/apidemo/javascript

20 kb of javascript, including the auto generated API bindings!

And more stuff is packed in there too. Best of all: D, through CGI, consistently does well or better than mod_php in my speed benchmarks. I've barely tried to optimize too; there's a lot of untapped potential.


If your host doesn't suck, dive into D on the web. You won't want to go back.)
May 13, 2011
"Robert Clipsham" <robert@octarineparrot.com> wrote in message news:iqjer9$1mai$1@digitalmars.com...
> On 13/05/2011 08:09, Jacob Carlborg wrote:
>>
>> How is it working out with a static type system, compared to a dynamic, for web development?
>
> How many times, while using a dynamically typed language, do you ever change the type of a variable? I've written a fair amount of PHP, and I rarely, if ever want my string to suddenly become an integer (if I do it generally needs validation/conversion anyway). When using my own and others code I frequently see type checks/conversions etc, it just makes the code ugly - with a staticly typed system you remove this overhead.
>
> Also, there's the auto keyword, and easily accessible function templates.
>

And templates for when you want a function to accept multiple types, and Variant for the few times when changing a variable's type might actually be useful.


May 13, 2011
"Adam D. Ruppe" <destructionator@gmail.com> wrote in message news:iqji6m$1se1$1@digitalmars.com...
> Jacob Carlborg wrote:
>> How is it working out with a static type system, compared to a dynamic, for web development?
>
> It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence.
>
> I can't tell you how many times I've made a minor mistake in PHP, Ruby, or Visual Basic and had it slip through to production because the code path was obscure enough to evade testing.
>

Yea, it all just comes from dynamic being sloppy and overly-permissive.

Before I switched my web development to Haxe (not remotely as good as D, but it beats the hell out of straight PHP/ActionScript), I had to do some stuff in ActionScript2. Anytime anything would go wrong (other than a syntax error), the compiler would accept it, and the *runtime* would accept it and just simply ignore it and move on. Not even an exception or log notice or anything. That alone turned development into an absolute nightmare. Nothing ever worked, you never had the slightest clue why, and it took forever to track the problem down to something that, invariably, would turn out to be something D would have caught immediately, usually at compile-time. And that was all in the name of being "forgiving". Blech. Bottom line, whether dynamically-typing or anything else: being overly-permissive sucks. What D permits you to do is tighten the damn leash.

>
> The to!() template in Phobos makes this pretty easy, or if you
> want default value and get/post combined, my cgi class has a request
> template:
>

to!() is absolutely awesome. OTOH, thanks to to!(), the conversion functions in every other language out there seem irritatingly poorly designed. ;) Anytime I have to do a conversion in Haxe, I always end up needing to reach for the std API reference. And even Haxe's API for conversions is pretty good compared to some other langauges.

> int a = cgi.request!int("a");
>
> That's similar to this in PHP:
>
> $a = 0;
> if(isset($_POST['a']))
>  $a = (int) $_POST['a'];
> else
> if(isset($_GET['a']))
>  $a = (int) $_GET['a'];
>
>
> PHP is so outrageously verbose. And the PHP is buggy compared to the D... if you do cgi.request!int("a", 10) and the user does a=txt, the PHP result is wrong. It's not quite fair to compare a function to a code collection though. A php function could do it right too.
>

Be glad it's not VB6, or worse, VBScript. I've had to do a lot of web dev in those languages in the past, and as horrible as PHP is overall, for outright verbosity it doesn't even compare to VB6/VBScript.

auto myVar = "foo";
$myVar = "foo";

vs:

Dim myVar As String
myVar = "foo"

Seriously?!

And don't get me started on VB's million-and-one different things you have to check for to see whether or not a string actually contains anything.

And then there's its arrays, which wouldn't be *too* bad if they didn't allow the staring index to be chosen completely at random. So, wanna find the length of an array? In D it's:

myArray.length

In PHP it's probably about the same as D. In VBScript, if you want to do it correctly, it's:

(UBound(myArray) - LBound(myArray))+1

Or you can do UBound(myArray)+1 and just pray that some stupid jackass doesn't actually try to use the "choose your array's lower bound", ahem, "feature".

I can just feel my sanity fading...

>
> auto table = cast(Table) document.getElementById("data-table");
> assert(table !is null); // fails if it isn't a <table> tag
>
> // use the table class's special functions
>
>
> Forms, Links, and other types of nodes are handled similarly. The Element base class though does most the simple operations. Being plain old inheritance, the virtual functions act dynamically enough.
>

You know, I used to absolutely love doing the rails-like thing of using HTML templates. And Terence Parr's StringTemplate even managed to convince me for awhile that such templates shouldn't have imperative logic.

But the more I watch your DOM approach and then continue using HTML templates (very mercifully, one that thankfully *does* allow imperative logic), the more fed up I'm starting to get with the template approach. Granted, I haven't used it yet, but I think you've got the right approach with your DOM stuff.

>
> And more stuff is packed in there too. Best of all: D, through CGI, consistently does well or better than mod_php in my speed benchmarks. I've barely tried to optimize too; there's a lot of untapped potential.
>

One of the things I've noticed never even seems to get mentioned is that even though CGI has had a stigma of high startup costs, *MANY* php installations, even on commercial shared hosting, have php set up to run as CGI. So even if php interpretation wasn't much slower than good compiled code, it *still* wouldn't usually have the speed advantage people have attributed to it.

>
> If your host doesn't suck, dive into D on the web. You won't want to go back.)

Won't want to go back to dynamic web scripting? Hell, I haven't even done any D CGI beyond a trivial hello world (for which I had to jump through *enormous* hoops to get working with my damn shared web hosts - and one of them, turns out, won't even support compiled CGI at all), and yet, I just plain don't want to *remain* with dynamic web scripting. :)

Another thing, too, that's really good about D being faster is that you can do a lot more before Apache/PHP/whatever decides to kill you off for taking too long. And you can realistically try to anticipate it, finish up any atomic operations, and die gracefully instead of risking corruption from broken atomicity.

That's getting to be a problem in my Haxe/PHP stuff. I have my code set up so that when there's an unhandled exception, it automatically tries to log it to three separate places: a logfile, the DB, and email. (And if any one of those fails, it still attempts the others and then tries to notify the others that the one failed. I'm really proud of the whole system :)) And, of course, a stack trace is included. But the problem is, this all takes (noticable) time, especially on PHP, so I risk loosing all the info that anything even went wrong at all just because the server killed it off for taking too long. And that's actually happened a few times on my local dev system (I *hope* it hasn't happened on the server...) Heck, I can usually tell when it's crashed even before I get the error page just because it'll take noticably longer than usual.

But what makes all that really bad is there seems to be a bug in either Haxe or PHP that causes stack traces to include *all* the functions called...ie, even the ones that have returned, instead of just the current call stack. So the *ahem* "call stack" ends up huge (and hard to use). And there's two things that make it far bigger than it even needs to be:

1. There's a big data structure I sometimes need (data that doesn't actually change - so it's converted automatically at build-time from a raw datafile to a direct hard-coded Haxe source file). But Haxe, and presumably PHP, doesn't allow compex literals. And even if it did, there's no such thing as pre-compiled PHP, so there's no such thing as a statically-initialized data segment. So the generated Haxe code has to actually build up the data structure at runtime. And the structure is somewhat large...and there's a limit on function size (don't recall if it's a Haxe or PHP limit)...so each piece of the data-building has to be put into it's own function. And there's currently hundreds of these little functions. So that makes the "broken stack trace" that much bigger and slower to build.

2. Haxe has runtime reflection, which is needed for it's, rather good, object database API. But the reflection works by keeping the info stored as...get this...XML...and then the XML is parsed to retrieve the actual data. Which is incredibly stupid, of course, but that's how it's done. And, of course, there's recursion involved in that XML parsing, so that bloats the big slow broken stack trace even more.

Although, all that reminds me, servers (especially shared hosts) can also have memory limits on scripts and CGI. But D's GC likes to just keep grabbing system RAM and only release back to the OS when really necessary, or when you tell it to. And even that can be blocked by false pointers. Have you had any problems with server memory caps and D's memory behavior?



May 13, 2011
Nick Sabalausky wrote:
> Be glad it's not VB6, or worse, VBScript.

Oh, I know it! One of my side jobs I picked up this year is maintaining somd old VBS program, using classic ASP.

There's so much nonsense. It doesn't help that the original author was horribly incompetent - he never used functions/subs, just copy and pasted everything. Over and over and over again.

(And to make it worse, the authors apparently didn't know HTML. Not a single standard link or form. *everything* is done as javascript or client side vbscript - mixed at random - calls in href attrs.)


My biggest problem when writing code for them though is that I instinctively put semicolons at the end of thoughts....

> CGI has had a stigma of high startup costs

I'm now convinced almost all of CGI's bad reputation is actually
Perl's problems that got misattributed. Starting a process is
quite fast. Starting a process, reading a script, compiling it,
and interpreting it... that's kinda slow. Moreover, Linux used to
be slower at forking new processes than it is today, so improvements
to the kernel help today too.

While my own benchmarks have shown a difference between mod_php and cgi hello world.... those differences disappear once you start using it on a real network. The slowdown of cgi is nothing next to even a fast network ping.


Now, none of the sites I've worked on have had millions of users. Maybe the tiny difference adds up. I doubt it, but I can't prove it.


But, let's face it. Virtually none of us have millions of users anyway. And if I did, I'm sure I can spare a few days to profile and fix the problem (either moving to persistent processes, or profiling Apache or whatever) in between my cash showers and golden baths. There's nothing inheriently slow about a D web site - quite the opposite, actually.


> Have you had any problems with server memory caps and D's memory behavior?

No, but at the same time, I don't process huge datasets yet abd
run most everything on servers I have root on. (there is a portion
that runs on a shared host and my D does work there, it has very
light duties so I don't know what would happen if it hit the limit.)

CGI programs tend to be fairly short lived though, so the GC might not be necessary at all. Once the request is complete, the process terminates, releasing everything at once.
May 14, 2011
> I haven't used it yet, but I think you've got the right approach with your DOM stuff.

For people who haven't read about this, I just wrote up a quick document about it:

http://arsdnet.net/web.d/dom.html

I really rambled at points, but I wanted to cover all the bases.
May 14, 2011
So I'm writing the official PHP library to access my work library.

Just spent 20 minutes trying to figure out why it wasn't working right.

The problem was ultimately here:

                $rurl .= "?" + $this->getArgString();

See the mistake? Neither did the stupid PHP interpreter. I hate it so much.
May 14, 2011
On 13.05.2011 17:19, Adam D. Ruppe wrote:

> It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence.

  Sure, there are many pros. And one significant drawback - it couldn't be easily embedded into HTML code.

  Either, you have to generate all your pages from inside of CGI script, or use templates - but the main advantage of PHP is that you can mix it with page text.

  Unfortunately, this is not really possible with D (or C, or C++ etc) - because the code needs to be compiled first, and that could be difficult to do if it is embedded into the page.

/Alexander
May 14, 2011
Alexander wrote:
>  Sure, there are many pros. And one significant drawback - it
>  couldn't be easily embedded into HTML code.

Two notes: 1) actually, you can. 2) You don't want to.

1) I wrote a little program called dhp.d - write D in a PHP style.

http://arsdnet.net/dhp.d

About 100 lines of D - not exactly a fancy program - but it shows a way you could do it.

Use dhp as an interpreter for your "script". You write

html here
<?d
  // D code here
?> // back to html


When dhp is run, it compiles the file on the fly. (This implementation doesn't cache, but it could and should)

Then, it passes control to the newly compiled file, which runs and outputs your stuff.


Literal html outside the <?d ?> tags is passed through just like php. This is implemented by putting quotes around it and cgi.writting it in the generated code.


2) While you could do it, you shouldn't do it. This is bad form even in PHP. See part of my DOM template writeup for a brief on why: http://arsdnet.net/web.d/dom.html

Basically, it gets ugly, fast.