www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - short thoughts on D (like my twitter)

reply Adam D. Ruppe <destructionator gmail.com> writes:
http://arsdnet.net/web.d/short-thoughts.html

I sometimes find little things I want to comment on, but it isn't
enough to make it's own page.

So I've decided to make one page where I'll dump them from time to
time, like a twitter, but not twitter because twitter sucks.


I started with something I just found pretty cool: using
to!enum("string") does super easy whitelisting of input! And, IFTI
lets you avoid repeating yourself if you want a default value.
Jun 10 2011
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 10/06/2011 18:12, Adam D. Ruppe wrote:
 http://arsdnet.net/web.d/short-thoughts.html

 I sometimes find little things I want to comment on, but it isn't
 enough to make it's own page.

 So I've decided to make one page where I'll dump them from time to
 time, like a twitter, but not twitter because twitter sucks.


 I started with something I just found pretty cool: using
 to!enum("string") does super easy whitelisting of input! And, IFTI
 lets you avoid repeating yourself if you want a default value.
Is there some way to subscribe to this? It seems like it could be quite interesting, if I can't subscribe via rss/atom/twitter I'll never see it though. -- Robert http://octarineparrot.com/
Jun 10 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Robert Clipsham wrote:
 Is there some way to subscribe to this?
I actually have a twitter account, so I'll use it for this: Actually posting the comments in twitter wouldn't work, but I'll post the link and a very brief summary on that account when I update this file or any other D related post.
Jun 10 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:istja4$1rua$1 digitalmars.com...
 http://arsdnet.net/web.d/short-thoughts.html

 So I've decided to make one page where I'll dump them from time to
 time, like a twitter, but not twitter because twitter sucks.
Heh, this quote wins teh intarnets. :) I've done the exact same thing with "blogging". I *don't* have a blog, blogs are stupid bullshit. But I do have something that just happens to arguably be a lot like a blog and uses a blogging engine ;)
 I started with something I just found pretty cool: using
 to!enum("string") does super easy whitelisting of input! And, IFTI
 lets you avoid repeating yourself if you want a default value.
It'd be better if there were just some sort of variant of "to" that indicated failure some other way (and "to" could be built out of it.) That way you wouldn't have to have the overhead of instantiating an exception (and any other throw/catch overhead there may or may not be) every time you have to use the default.
Jun 10 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-10 12:21, Nick Sabalausky wrote:
 "Adam D. Ruppe" <destructionator gmail.com> wrote in message
 news:istja4$1rua$1 digitalmars.com...
 
 http://arsdnet.net/web.d/short-thoughts.html
 
 So I've decided to make one page where I'll dump them from time to
 time, like a twitter, but not twitter because twitter sucks.
Heh, this quote wins teh intarnets. :) I've done the exact same thing with "blogging". I *don't* have a blog, blogs are stupid bullshit. But I do have something that just happens to arguably be a lot like a blog and uses a blogging engine ;)
 I started with something I just found pretty cool: using
 to!enum("string") does super easy whitelisting of input! And, IFTI
 lets you avoid repeating yourself if you want a default value.
It'd be better if there were just some sort of variant of "to" that indicated failure some other way (and "to" could be built out of it.) That way you wouldn't have to have the overhead of instantiating an exception (and any other throw/catch overhead there may or may not be) every time you have to use the default.
It came up in a discussion of isNumeric the other day (actually I think that it was on a bug report regarding isNumeric) that it would be benificial to add functions to std.conv which indicated whether to or parse would succeed or not, so that code where failure was likely could check first rather than having the overhead of the ConvException (which is frustratingly significant at this point). Unfortunately, there's a high risk that you would have to duplicate what to and parse are doing to do that (especially if you want all of those functions to be efficient), so I don't know what we're going to do about it. It _is_ something that should be looked into however. - Jonathan M Davis
Jun 10 2011
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Nick Sabalausky wrote:
 But I do have something that just happens to arguably be a lot like
 a blog and uses a blogging engine ;)
Gah, only weens use blogging engines! I tend to just write my stuff as plain html files (like you can see here). Sometimes I'll factor out common things, but I usually don't venture far from plain text. On the feed issue, that's something that doesn't bug me either - I just keep a list of sites I like in my brain and check them whenever I have nothing better to do. This perhaps only works for me because I read so few sites!
 It'd be better if there were just some sort of variant of "to"
 that indicated failure some other way (and "to" could be built
 out of it.)
Indeed, but nothing in phobos currently can quite do that... Some quick commentary on IFTI: I actually discovered this by accident. Of course, I use IFTI all over the place, like most D programmers probably do. But, since the T argument was a default one here, I often didn't specify it: int a = cgi.request!int("a"); (Why use this instead of to!int(cgi.get["a"])? The request implementation checks both get and post.) Then, I started adding it, but still specified: int a = cgi.request!int("a", 100); One time, I just didn't write the template argument and it still worked! While it's a really mundane feature of D, I still felt a bit of "hey cool" when it worked. The to!enum was another thing I didn't expect. I thought it would do the same as casting an int, but it works from name, which is actually very cool. More user friendly, and that white listing aspect is also pretty useful. mysql.query("select * from users where " ~ to!string(cgi.request("field", Field.name)) ~ " = ?", value); Building a sql string like that is fairly ugly, and normally, it'd be /completely/ insane. You're just begging for trivially easy sql injections. But, thanks to the enum acting as a whitelist, you actually can do that in D. (Note that while I'm putting this in the web.d directory and talking about cgi, lots of this stuff works on the command line too. Imagine an enum for command line flags - converting is easy, you can to!string one of the enums safely, you can list the arguments using reflection, and final switch() can be used to ensure you cover them all! D's enums have a lot of hidden treasures.)
Jun 10 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:isu59p$6sd$1 digitalmars.com...
 Nick Sabalausky wrote:
 But I do have something that just happens to arguably be a lot like
 a blog and uses a blogging engine ;)
Gah, only weens use blogging engines! I tend to just write my stuff as plain html files (like you can see here). Sometimes I'll factor out common things, but I usually don't venture far from plain text.
Heh, I have no idea what a "ween" is. I gotta (partially) agree though, I've yet to find a blogging engine that I'm particularly happy with. The main reason I didn't want to go with plain HTML though was because that makes creating and updating navigation a pain. Maybe something like Ddoc could take care of that, though. But I also like allowing comments (with captcha), because then I actually get occasional feedback. And some people do like RSS (more below...). Of course, as you can see, it wouldn't take many features to make me happy. And heck, I don't really even *need* the ability to update through a web interface (although that does make it easier than reaching for my ftp app and updating a bunch of files). So it would probably be pretty easy to just make something myself that I'd be happy with. And I've been thinking about doing that. But even as simple as it would be, it's just one more thing on top my pile of pet projects that's already probably big enough for three lifetimes...
 On the feed issue, that's something that doesn't bug me either -
 I just keep a list of sites I like in my brain and check them
 whenever I have nothing better to do. This perhaps only works
 for me because I read so few sites!
I've tried out RSS feeds before, but ended up never really getting any use out of them. I think I'm in the same boat as you. These D NGs are about all I care about being up-to-date on, and I already check them directly anyway. Of course, the ironly is despite never using them, I've actually implemented RSS feeds for two different paid jobs (They were surprisingly easy). In fact, I seem to have a pattern of occasionally winding up working on things that I don't personally use: I've worked on a WAP/WML site (remember those?) and dabbeld a little in SymbianOS dev with C/C++ and J2ME without having ever actually owned a cell. Anyway, I do like to at least provide an RSS/ATOM feed since it is useful for some people.
 Some quick commentary on IFTI:

 I actually discovered this by accident. Of course, I use IFTI
 all over the place, like most D programmers probably do.

 But, since the T argument was a default one here, I often didn't
 specify it:

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

 (Why use this instead of to!int(cgi.get["a"])? The request
 implementation checks both get and post.)

 Then, I started adding it, but still specified:

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


 One time, I just didn't write the template argument and it
 still worked!


 While it's a really mundane feature of D, I still felt a bit
 of "hey cool" when it worked.



 The to!enum was another thing I didn't expect. I thought it would
 do the same as casting an int, but it works from name, which is
 actually very cool. More user friendly, and that white listing
 aspect is also pretty useful.

 mysql.query("select * from users where " ~
  to!string(cgi.request("field", Field.name)) ~
 " = ?", value);


 Building a sql string like that is fairly ugly, and normally, it'd
 be /completely/ insane. You're just begging for trivially easy
 sql injections.


 But, thanks to the enum acting as a whitelist, you actually can
 do that in D.


 (Note that while I'm putting this in the web.d directory and talking
 about cgi, lots of this stuff works on the command line too. Imagine
 an enum for command line flags - converting is easy, you can
 to!string one of the enums safely, you can list the arguments
 using reflection, and final switch() can be used to ensure you
 cover them all!

 D's enums have a lot of hidden treasures.)
Hmm, so basically: The surprises are pleasant ones. Reminds me of a certain other language... ;)
Jun 11 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Nick Sabalausky wrote:
 Heh, I have no idea what a "ween" is.
Word I made up... meant to be a less serious version of wimpy loser. :)
  The main reason I didn't want to go with plain HTML though was
 because that makes creating and updating navigation a pain.
Yea, some kind of helper program is good there.. I'll probably start using one too if I add enough content. For a while, I used a little program written in C to build that stuff for me... for all the stuff I write for dynamic websites, I take lots of steps to avoid using them myself!
  (although that does make it easier than reaching for my ftp app
 and updating a bunch of files)
I cheat here too - my website is hosted from my computer, so I write the files in place!
 Hmm, so basically: The surprises are pleasant ones. Reminds me of
 a certain other language... ;)
VB6??????????!?!?!!?
Jun 11 2011
parent reply Jeff Nowakowski <jeff dilacero.org> writes:
On 06/11/2011 10:41 AM, Adam D. Ruppe wrote:
 Nick Sabalausky wrote:
 Heh, I have no idea what a "ween" is.
Word I made up... meant to be a less serious version of wimpy loser. :)
Sorry, you didn't make that word up. It's in the Urban Dictionary: http://www.urbandictionary.com/define.php?term=ween And I know it well from my rec.games.netrek days as a common insult.
Jun 11 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jeff Nowakowski" <jeff dilacero.org> wrote in message 
news:it033e$1g7a$1 digitalmars.com...
 On 06/11/2011 10:41 AM, Adam D. Ruppe wrote:
 Nick Sabalausky wrote:
 Heh, I have no idea what a "ween" is.
Word I made up... meant to be a less serious version of wimpy loser. :)
Sorry, you didn't make that word up. It's in the Urban Dictionary: http://www.urbandictionary.com/define.php?term=ween And I know it well from my rec.games.netrek days as a common insult.
You could probably string any random letters together and it would be in urban dictionary.
Jun 11 2011
prev sibling next sibling parent Sean Kelly <sean invisibleduck.org> writes:
How about drdobbs.com?  Short-form entries are common there.

Sent from my iPhone

On Jun 11, 2011, at 4:33 AM, "Nick Sabalausky" <a a.a> wrote:

 "Adam D. Ruppe" <destructionator gmail.com> wrote in message=20
 news:isu59p$6sd$1 digitalmars.com...
 Nick Sabalausky wrote:
 But I do have something that just happens to arguably be a lot like
 a blog and uses a blogging engine ;)
=20 Gah, only weens use blogging engines! =20 I tend to just write my stuff as plain html files (like you can see here). Sometimes I'll factor out common things, but I usually don't venture far from plain text. =20
=20 Heh, I have no idea what a "ween" is. I gotta (partially) agree though, I'=
ve=20
 yet to find a blogging engine that I'm particularly happy with. The main=20=
 reason I didn't want to go with plain HTML though was because that makes=20=
 creating and updating navigation a pain. Maybe something like Ddoc could=20=
 take care of that, though. But I also like allowing comments (with captcha=
),=20
 because then I actually get occasional feedback. And some people do like R=
SS=20
 (more below...).
=20
 Of course, as you can see, it wouldn't take many features to make me happy=
.=20
 And heck, I don't really even *need* the ability to update through a web=20=
 interface (although that does make it easier than reaching for my ftp app=20=
 and updating a bunch of files). So it would probably be pretty easy to jus=
t=20
 make something myself that I'd be happy with. And I've been thinking about=
=20
 doing that. But even as simple as it would be, it's just one more thing on=
=20
 top my pile of pet projects that's already probably big enough for three=20=
 lifetimes...
=20
=20
 On the feed issue, that's something that doesn't bug me either -
 I just keep a list of sites I like in my brain and check them
 whenever I have nothing better to do. This perhaps only works
 for me because I read so few sites!
=20
=20 I've tried out RSS feeds before, but ended up never really getting any use=
=20
 out of them. I think I'm in the same boat as you. These D NGs are about al=
l=20
 I care about being up-to-date on, and I already check them directly anyway=
.
=20
 Of course, the ironly is despite never using them, I've actually implement=
ed=20
 RSS feeds for two different paid jobs (They were surprisingly easy). In=20=
 fact, I seem to have a pattern of occasionally winding up working on thing=
s=20
 that I don't personally use: I've worked on a WAP/WML site (remember those=
?)=20
 and dabbeld a little in SymbianOS dev with C/C++ and J2ME without having=20=
 ever actually owned a cell.
=20
 Anyway, I do like to at least provide an RSS/ATOM feed since it is useful=20=
 for some people.
=20
=20
 Some quick commentary on IFTI:
=20
 I actually discovered this by accident. Of course, I use IFTI
 all over the place, like most D programmers probably do.
=20
 But, since the T argument was a default one here, I often didn't
 specify it:
=20
 int a =3D cgi.request!int("a");
=20
 (Why use this instead of to!int(cgi.get["a"])? The request
 implementation checks both get and post.)
=20
 Then, I started adding it, but still specified:
=20
 int a =3D cgi.request!int("a", 100);
=20
=20
 One time, I just didn't write the template argument and it
 still worked!
=20
=20
 While it's a really mundane feature of D, I still felt a bit
 of "hey cool" when it worked.
=20
=20
=20
 The to!enum was another thing I didn't expect. I thought it would
 do the same as casting an int, but it works from name, which is
 actually very cool. More user friendly, and that white listing
 aspect is also pretty useful.
=20
 mysql.query("select * from users where " ~
 to!string(cgi.request("field", Field.name)) ~
 " =3D ?", value);
=20
=20
 Building a sql string like that is fairly ugly, and normally, it'd
 be /completely/ insane. You're just begging for trivially easy
 sql injections.
=20
=20
 But, thanks to the enum acting as a whitelist, you actually can
 do that in D.
=20
=20
 (Note that while I'm putting this in the web.d directory and talking
 about cgi, lots of this stuff works on the command line too. Imagine
 an enum for command line flags - converting is easy, you can
 to!string one of the enums safely, you can list the arguments
 using reflection, and final switch() can be used to ensure you
 cover them all!
=20
 D's enums have a lot of hidden treasures.)
=20 Hmm, so basically: The surprises are pleasant ones. Reminds me of a certai=
n=20
 other language... ;)
=20
=20
=20
Jun 11 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/11/11, Sean Kelly <sean invisibleduck.org> wrote:
 How about drdobbs.com?  Short-form entries are common there.
After they've completely screwed up all the existing links to old articles, I don't know why anyone would want to write there.
Jun 11 2011
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
Another thing that I'm not even ready to write html about,
but it works in great part thanks to alias.

===
import arsd.web;

class TestObject : ApiObject {
	this(Site site, string identifier) {
		id = identifier;
	}

	string id;

	string sayHello() {
		return "hello from " ~ id;
	}
}

class Site : ApiProvider {
	alias .TestObject TestObject;
}

mixin FancyMain!(Site);

===

http://arsdnet.net/cgi-bin/objdemo/TestObject/adam/say-hello

That url calls:

auto obj = new TestObject(site, "adam");
auto result = obj.sayHello();

// output the return value to the user in a suitable format...
cgi.write(wrapIn("document", formatAs("html", result)));

behind the scenes. That formatAs() function can do some magical
things too. I'll write about it when I do my second html templating
article. override Element makeHtmlElement() can do some magical
things...

Wow, sidetracking!

class ApiProvider is the centerpiece of web.d. It uses D's
reflection capabilities to make a collection of standard D
methods, structs, and enums available to the outside world.

Your functions are accessible through a web browser interface
(plain html documents and forms) a javascript interface, and
whatever other external programs you want; even a shell script
can access unauthenticated functions in about 20 lines if you
have curl.


Anyway, until today, the access was for the most part, only procedural style.

http://arsdnet.net/cgi-bin/apidemo/get-a-box?color=red

Translates directly to getABox(Color.red); That's what you'd do
for all the site's functions.


Now, you can have classes too, as seen above. Previously, I'd
write things like

void powerOnVm(int vmId) { auto vm = VM.get(vmId); vm.powerOn(); }

Now, I should be able to just expose that VM object directly to
the user, without having to manually write that wrapper code!


I'll save the why details for when I do the full writeup (which
will be after I try actually using this for something - so I can
be sure it's actually useful the way it is now).

But the how has one thing I find very cool: the alias.



When using web.d, the magic reflection is only called on a single
class, and all a classes members must exist in one file...

...unless you add more with alias!


D's alias lets you introduce any kind of name into your class,
from anywhere. When the derivedMembers loop is run to generate
the reflection info, it sees those alias members too.

===
int foo() { return 10; }

class CoolApi : ApiProvider {
  alias .foo foo;
}

mixin FancyMain!(CoolApi);
===

http://arsdnet.net/cgi-bin/objdemo/foo

Prints 10 - the free function becomes a part of the class, sort
of. Of course, being a free function, it can't actually access
the classes instance variables, and passing parameters to it
through the web interface is probably no good (suppose it needs
a database handle... the website user certainly can't provide
that!).

So, aliasing free functions isn't of much use.


Aliasing structs, enums, and classes though? Very nice. Write
your structs in another file and expose them to the public site
with a single alias line. Share enums from another module with
the world just by aliasing it in.


For the object demo, I did a class this way. The TestObject
could be moved to another module, and include functions the
whole thing can use. Yay! (This is why the first argument to the
constructor is your ApiProvider instance btw, so it can access
those instance variables, putting it ahead of free functions.)


The ApiProvider module might be nothing more* than a list of
imports and aliases, exposing certain portions of your
application to the public. Currently though, it ensures the
exposed classes all derive from ApiObject, but there's actually
no technical reason for this; I just thought it looked cleaner.
It might change as I actually use it.

structs and enums have no such restriction - you can alias them
in to your heart's content. But, their methods aren't accessible
from the outside like classes.

(On the other hand, their data members are. Class data members
are never exposed here; part of that is the procedural roots,
and part of it is that I assume instance variables are more likely
database handles and such than things the end user ought to have
access to.

Similarly, http://arsdnet.net/cgi-bin/objdemo/TestObject/adam/
gives no such method instead of dumping the variables. I'm
considering tying that into a particular method which can return
a struct or something.)


* Well, ApiProvider is also responsible for custom data formatting
for output to the browser, so it'd probably still do that. But
it could be limited to pure view like activities, without any
site logic function implementations.


Speaking of alias, another cool thing: alias one class method
to another name. The reflection picks it up, so it's now accessible
to the browser user both ways too! This surprised me actually -
I figured alias wouldn't show up in the reflection, but it did.
(of course, my current implementation generates separate wrapper
delegates for each alias... but meh, my implementation is ugly.
the results are beautiful :) )



Anyway, this ended up being pretty long! I'm just continually
amazed with the cool things D's most mundane features allow.
First enum and now alias... will the fun never end?
Jun 10 2011
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
Tumblr?  It doesn't have the length limitation.=20

Sent from my iPhone

On Jun 10, 2011, at 10:12 AM, "Adam D. Ruppe" <destructionator gmail.com> wr=
ote:

 http://arsdnet.net/web.d/short-thoughts.html
=20
 I sometimes find little things I want to comment on, but it isn't
 enough to make it's own page.
=20
 So I've decided to make one page where I'll dump them from time to
 time, like a twitter, but not twitter because twitter sucks.
=20
=20
 I started with something I just found pretty cool: using
 to!enum("string") does super easy whitelisting of input! And, IFTI
 lets you avoid repeating yourself if you want a default value.
Jun 11 2011