www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D For A Web Developer

reply "James" <jamesmp98 gmail.com> writes:
I have a friend that is a web developer. I, however want to 
collaborate with him, so I am trying to get him to learn D. I  
don't know how to persuade him! How can D be used to greatly 
assist an HTML5/JavaScript web developer? I decided to go here to 
get some good answers. How can D be used to interopt with modern 
web development?
Apr 29 2014
next sibling parent reply Etienne <etcimon gmail.com> writes:
On 2014-04-29 10:41 AM, James wrote:
 I have a friend that is a web developer. I, however want to collaborate
 with him, so I am trying to get him to learn D. I don't know how to
 persuade him! How can D be used to greatly assist an HTML5/JavaScript
 web developer? I decided to go here to get some good answers. How can D
 be used to interopt with modern web development?
You should ask this in http://forum.rejectedsoftware.com/groups/rejectedsoftware.vibed/ But while we're here, maybe you could send him a link to http://vibed.org/ along with a link to http://dlang.org/phobos/std_algorithm.html that he could read when he has 10 minutes I don't know how else you could convince him. Possibly benchmarks? http://atilanevesoncode.wordpress.com/2013/12/05/go-vs-d-vs-erlang-vs-c-in-real-life-mqtt-broker-implementation-shootout/ Or an example of a dynamic web project backend? https://github.com/rejectedsoftware/vibe.d/tree/master/examples/web He might not be so familiar with type safety though, so then your arguments will have to be more technical - type safety is the only way you can ever scale a project because most bugs are caught by the compiler. He can keep using his front-end libraries too. Browsers don't run D code, they simply request bytes from it. Good luck!
Apr 29 2014
parent "Chris" <wendlec tcd.ie> writes:
On Tuesday, 29 April 2014 at 15:17:10 UTC, Etienne wrote:
 On 2014-04-29 10:41 AM, James wrote:
 I have a friend that is a web developer. I, however want to 
 collaborate
 with him, so I am trying to get him to learn D. I don't know 
 how to
 persuade him! How can D be used to greatly assist an 
 HTML5/JavaScript
 web developer? I decided to go here to get some good answers. 
 How can D
 be used to interopt with modern web development?
You should ask this in http://forum.rejectedsoftware.com/groups/rejectedsoftware.vibed/ But while we're here, maybe you could send him a link to http://vibed.org/ along with a link to http://dlang.org/phobos/std_algorithm.html that he could read when he has 10 minutes I don't know how else you could convince him. Possibly benchmarks? http://atilanevesoncode.wordpress.com/2013/12/05/go-vs-d-vs-erlang-vs-c-in-real-life-mqtt-broker-implementation-shootout/ Or an example of a dynamic web project backend? https://github.com/rejectedsoftware/vibe.d/tree/master/examples/web He might not be so familiar with type safety though, so then your arguments will have to be more technical - type safety is the only way you can ever scale a project because most bugs are caught by the compiler. He can keep using his front-end libraries too. Browsers don't run D code, they simply request bytes from it. Good luck!
Agree. Give vibe.d a try. If your friend uses dub to build it, it should be pretty easy to get started. A basic server app is very simple and straight forward to implement with vibe.d. Once the server is running he can use his existing html / js files (the server app just, well, "serves" them), or he can do more fancy script like stuff with diet templates: http://vibed.org/docs#html-templates and http://vibed.org/templates/diet And yes, vibe.d is by an order of magnitude faster than your usual web infrastructures.
Apr 29 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
I recently started a Ruby on Rails job and using it makes me 
really, really miss the high productivity and ease of use D 
offers. (And, of course, a dynamic site in D runs about 3x faster 
out of the box than hello world served by Rails, zero effort in 
optimization. And "rake test", just shoot me, I'd rather rebuild 
a C++ project from scratch, at least that'll finish before the 
heat death of the universe.)
Apr 29 2014
next sibling parent reply Etienne <etcimon gmail.com> writes:
On 2014-04-29 11:27 AM, Adam D. Ruppe wrote:
 I recently started a Ruby on Rails job and using it makes me really,
 really miss the high productivity and ease of use D offers. (And, of
 course, a dynamic site in D runs about 3x faster out of the box than
 hello world served by Rails, zero effort in optimization. And "rake
 test", just shoot me, I'd rather rebuild a C++ project from scratch, at
 least that'll finish before the heat death of the universe.)
That's funny b/c most people say RoR made them love web development. If the D community could organize itself the same way RoR is around web dev, I doubt any other web scripting language could pursue existence.
Apr 29 2014
next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Apr 29, 2014 at 11:55:11AM -0400, Etienne via Digitalmars-d wrote:
 On 2014-04-29 11:27 AM, Adam D. Ruppe wrote:
I recently started a Ruby on Rails job and using it makes me really,
really miss the high productivity and ease of use D offers. (And, of
course, a dynamic site in D runs about 3x faster out of the box than
hello world served by Rails, zero effort in optimization. And "rake
test", just shoot me, I'd rather rebuild a C++ project from scratch,
at least that'll finish before the heat death of the universe.)
That's funny b/c most people say RoR made them love web development.
[...] That's not what I hear. My cousin, who does RoR, hates it with a passion, and wishes she could get out of it. But unfortunately, she can't. I don't use RoR personally, though, so I can't speak for it myself. T -- I see that you JS got Bach.
Apr 29 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 29 April 2014 at 15:55:13 UTC, Etienne wrote:
 That's funny b/c most people say RoR made them love web 
 development.
That's probably because they went into it with very little experience with the alternatives. I was spoiled by my web.d and friends, as well as knowing how to use a real relational database, so getting on the Rails to me is like going back into the stone age. But if you came from mysql 3 and PHP 4 or some other primitive trash, RoR might seem like the best thing ever. I do kinda like the rails console repl tho. Of course, I kinda have that with cgi.d too, you can call its methods on the regular command line pretty easily, but that doesn't let you build up state as easily for quick changes and I do like that. (Maybe I'll offer such with my script.d, should be easy to add :P) the rest of it tho is just awful.
Apr 29 2014
parent reply "Chris" <wendlec tcd.ie> writes:
On Tuesday, 29 April 2014 at 17:09:53 UTC, Adam D. Ruppe wrote:
 On Tuesday, 29 April 2014 at 15:55:13 UTC, Etienne wrote:
 That's funny b/c most people say RoR made them love web 
 development.
That's probably because they went into it with very little experience with the alternatives. I was spoiled by my web.d and friends, as well as knowing how to use a real relational database, so getting on the Rails to me is like going back into the stone age. But if you came from mysql 3 and PHP 4 or some other primitive trash, RoR might seem like the best thing ever. I do kinda like the rails console repl tho. Of course, I kinda have that with cgi.d too, you can call its methods on the regular command line pretty easily, but that doesn't let you build up state as easily for quick changes and I do like that. (Maybe I'll offer such with my script.d, should be easy to add :P) the rest of it tho is just awful.
Is there any documentation for web.d, including example apps? I'm using vibe.d at the moment and rolled my own customized DOM tree stuff (that was before I knew dom.d existed). I basically implemented the most important JS features for DOM manipulation and added stuff I'd always wanted in JS.
Apr 30 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 09:22:06 UTC, Chris wrote:
 Is there any documentation for web.d, including example apps?
Not much, I've done some before but it is pretty scattered and I don't even know where it all is right now.
 I basically implemented the most important JS features for DOM 
 manipulation and added stuff I'd always wanted in JS.
Yeah, dom.d is kinda my magical group of nice convenience too. The .addChild() helper makes building a tree in code so simple that I rarely even thing about innerHTML anymore. addChild takes a tag name and two child strings which are customized based on the tag name: addChild("a", "Link test", "http://link-target.com/"); // makes <a href="httpp....">Link test</a> addChild("span", "foo", "bar"); // makes <span class="bar">foo</span> addChild("div", Html("<b>lol</b>")); // <div><b>lol</b></div> (normally, the second argument is innerText and the third argument is the big customization point.) dom.d's Form class makes them stupid-simple to use too. auto form = document.requireSelector!Form("#my-form"); form.setValue("something", "else"); setValue finds the element with that particular name and sets teh value based on what it is. So if it is an <input>, it sets value. If it is a <textarea>, it sets innerText. If it is <select>, it sets the attribute on the right <option>, or can add an option if needed. It can also implicitly create a hidden element if needed. The Link class has a similar function for link URL params. And, of course, these can be done in a loop: void forwardParams() { foreach(k, v; cgi.post) form.setValue(k, v); } so simple!
Apr 30 2014
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/29/2014 11:55 AM, Etienne wrote:
 On 2014-04-29 11:27 AM, Adam D. Ruppe wrote:
 I recently started a Ruby on Rails job and using it makes me really,
 really miss the high productivity and ease of use D offers. (And, of
 course, a dynamic site in D runs about 3x faster out of the box than
 hello world served by Rails, zero effort in optimization. And "rake
 test", just shoot me, I'd rather rebuild a C++ project from scratch, at
 least that'll finish before the heat death of the universe.)
That's funny b/c most people say RoR made them love web development. If the D community could organize itself the same way RoR is around web dev, I doubt any other web scripting language could pursue existence.
Ruby on Rails popularized MVC web frameworks, and that was a significant step forward from the stuff that came before, like PHP, ASP or even arguably ASP.NET (or *shudder* ColdFusion). I think that's always been RoR's main benefit and appeal. But since then, every other language under the sun (or rather, under florescent lights?) has grown its own MVC web framework, so Rails's biggest distinguishing characteristic now is just that it's in Ruby. And Ruby is kinda famous for having little significance outside of Rails itself. (Although, I did find Rake quite beneficial in an older project with a rather complex build. Course, these days D/Phobos has gotten good enough I'd just do a build script in D.) At least that's my impression of Ruby and Rails.
Apr 29 2014
parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 29.04.2014 19:45, schrieb Nick Sabalausky:
 On 4/29/2014 11:55 AM, Etienne wrote:
 On 2014-04-29 11:27 AM, Adam D. Ruppe wrote:
 I recently started a Ruby on Rails job and using it makes me really,
 really miss the high productivity and ease of use D offers. (And, of
 course, a dynamic site in D runs about 3x faster out of the box than
 hello world served by Rails, zero effort in optimization. And "rake
 test", just shoot me, I'd rather rebuild a C++ project from scratch, at
 least that'll finish before the heat death of the universe.)
That's funny b/c most people say RoR made them love web development. If the D community could organize itself the same way RoR is around web dev, I doubt any other web scripting language could pursue existence.
Ruby on Rails popularized MVC web frameworks, and that was a significant step forward from the stuff that came before, like PHP, ASP or even arguably ASP.NET (or *shudder* ColdFusion). I think that's always been RoR's main benefit and appeal. But since then, every other language under the sun (or rather, under florescent lights?) has grown its own MVC web framework, so Rails's biggest distinguishing characteristic now is just that it's in Ruby. And Ruby is kinda famous for having little significance outside of Rails itself. (Although, I did find Rake quite beneficial in an older project with a rather complex build. Course, these days D/Phobos has gotten good enough I'd just do a build script in D.) At least that's my impression of Ruby and Rails.
I was already doing RoR back in 1999, but it was with our own in-house TCL Apache/IIS module in a Portuguese startup, far far away from Silicon Valley and loosely based in AOL Server concepts. We eventually moved into .NET, at the time only known to Microsoft partners like our mother company, before it was announced to the world. It was a very good learning experience, building a whole stack from the ground up, back in the early web days. We already had Active Record and MVC with security layers and scaffolding, just in TCL and unknown to the world. -- Paulo
Apr 29 2014
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 2014-04-29 at 20:04 +0200, Paulo Pinto via Digitalmars-d wrote:
[…]
 I was already doing RoR back in 1999, but it was with our own in-house 
 TCL Apache/IIS module in a Portuguese startup, far far away from Silicon 
 Valley and loosely based in AOL Server concepts.
[…]
 We already had Active Record and MVC with security layers and 
 scaffolding, just in TCL and unknown to the world.
Californians insist that everything is invented in California, and all other USAnians believe them. It is about time Europeans stopped believing them. Especially as everything in the future will be invented in China. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 29 2014
prev sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 29 Apr 2014 11:55:11 -0400
Etienne via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 That's funny b/c most people say RoR made them love web development.
 If the D community could organize itself the same way RoR is around
 web dev, I doubt any other web scripting language could pursue
 existence.
no, please, no! the latest thing D needs is a bunch of php-coders!
Apr 29 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-29 17:27, Adam D. Ruppe wrote:
 I recently started a Ruby on Rails job and using it makes me really,
 really miss the high productivity and ease of use D offers.
I'm curious to why you think D is more productive and easier to use. -- /Jacob Carlborg
Apr 29 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 29 April 2014 at 19:06:59 UTC, Jacob Carlborg wrote:
 I'm curious to why you think D is more productive and easier to 
 use.
A lot of things, mostly focusing around having the compiler to help refactor with confidence (the importance of this really can't be understated) and having libraries that fit better. The speed is a nice bonus too, having to spend half a minute just waiting for the tests to run really grates me. But wrt libraries, ActiveRecord is unbelievably awful, for example. It is a bad idea from the ground up: why, oh why are we reinventing the database? erb templates are painful to use too, and so is the routing. I don't understand why routing isn't done automatically for the common case. The scaffolding is a pain too. Contrast to what web.d does: given a function signature, it automatically generates a form for it (using type information to select correct widgets) and can format the response in several forms automatically including plain text, html list, html table, json, xml, csv, and a custom template. Maybe Rails can do this stuff and I'm too much of a n00b, but the other experienced team members say the way we're doing it is pretty standard and I'm just not impressed. I can just get stuff done in D in a fraction of a time it takes to do even less in RoR.
Apr 29 2014
next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 2014-04-29 at 22:09 +0000, Adam D. Ruppe via Digitalmars-d
wrote:
[…]
 I can just get stuff done in D in a fraction of a time it takes 
 to do even less in RoR.
This is the stuff marketing campaigns are made from. As well as informing the cabal that is this mailing list, there needs to be tweets, Facebook, G+, and proper publishing articles of people switching from RoR, Grails, Django to web.d and vibe.d and discovering (measured and guaranteed) significant performance benefits in both time to market and run time. Go has gained much of it's traction from provably and consistently producing simpler, faster and more reliable systems that C, C++, Python, etc. and getting articles about the success out there. HN is all very well but it is really another inward looking cabal. Articles about rewrites of systems written in sober yet humorous tones presenting real benefits will over a period of a couple of year generate a groundswell of support. D may be a lot older than Go, but there is a lot to be learned from the way non-Google folk created the "buzz" for Go by doing and publishing data about, as well as chatting on the mailing list. It also helped that a faction in Canonical switched from Python to Go and got on and did things that contributed positively to Ubuntu. Whatever your feelings towards Canonical and Ubuntu, their use of Go has contributed strongly to the progress and acceptance of the language. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 29 2014
next sibling parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
It may be a good time to repeat, we need a marketing manager for 
D!
Somebody really really needs to focus on getting us out there.
Apr 29 2014
parent reply "Danny Weldon" <danny.weldon gmail.com> writes:
On Wednesday, 30 April 2014 at 04:22:52 UTC, Rikki Cattermole 
wrote:
 It may be a good time to repeat, we need a marketing manager 
 for D!
 Somebody really really needs to focus on getting us out there.
If somebody has some time, they could post a solution in D to this problem: http://codegolf.stackexchange.com/questions/26323/how-slow-is-python-really-or-how-fast-is-your-language It all helps to get the language visible.
May 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Danny Weldon:

 If somebody has some time, they could post a solution in D to 
 this problem:

 http://codegolf.stackexchange.com/questions/26323/how-slow-is-python-really-or-how-fast-is-your-language

 It all helps to get the language visible.
Here are my solutions: http://forum.dlang.org/thread/pvojsrqmaksqwokuekhk forum.dlang.org I don't have a Stackexchange account. You are welcome to post the two solutions (of two different problems). Bye, bearophile
May 04 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Sunday, 4 May 2014 at 10:04:12 UTC, bearophile wrote:
 Danny Weldon:

 If somebody has some time, they could post a solution in D to 
 this problem:

 http://codegolf.stackexchange.com/questions/26323/how-slow-is-python-really-or-how-fast-is-your-language

 It all helps to get the language visible.
Here are my solutions: http://forum.dlang.org/thread/pvojsrqmaksqwokuekhk forum.dlang.org I don't have a Stackexchange account. You are welcome to post the two solutions (of two different problems). Bye, bearophile
I'm not able to run either version on DPaste. It fails to compile on both examples with no error message. Both example compile fine locally with DMD 2.065, however. Your C++ translation: ~277ms Your second version: ~2.34ms/round I just compiled and ran each binary a few times, so these might not be good measurements. I compiled both versions without -inline, as they ran slower with it enabled. LDC might do a better job with this.
May 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Meta:

 Your C++ translation: ~277ms
 Your second version:  ~2.34ms/round
Both D programs are translations of C++ programs.
 LDC might do a better job with this.
I have developed those two programs using ldc2, so the usage of ldc2 is encouraged, and inlining is necessary for both programs. Generally don't use DMD for benchmark contests like this one. Bye, bearophile
May 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
The Nimrod version partially unrolls the recursion 4 times. How 
hard is this to do in D?

http://codegolf.stackexchange.com/questions/26459/how-high-can-you-go-a-codingalgorithms-challenge

Bye,
bearophile
May 04 2014
parent "Sergey" <httpal gmail.com> writes:
I just want to write a web client app on D for medical 
institutions. It must be a complicated interface. What tools 
(GUI) should I use for quick programming?
Can I somehow abstract from web programming?

Thanks in advance.
Regards, Sergey
May 11 2014
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
Digitalmars-d wrote:
 On Tue, 2014-04-29 at 22:09 +0000, Adam D. Ruppe via 
 Digitalmars-d
 wrote:
 […]
 I can just get stuff done in D in a fraction of a time it 
 takes to do even less in RoR.
This is the stuff marketing campaigns are made from. As well as informing the cabal that is this mailing list, there needs to be tweets, Facebook, G+, and proper publishing articles of people switching from RoR, Grails, Django to web.d and vibe.d and discovering (measured and guaranteed) significant performance benefits in both time to market and run time.
I have a friend who has switched to vibe.d after being Erlang Cowboy devoted user for years. Trying to convince him to write an article about it but no luck so far :( Reason to switch in two words : "static typing".
Apr 29 2014
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 04:42:09 UTC, Dicebot wrote:
 I have a friend who has switched to vibe.d after being Erlang 
 Cowboy devoted user for years. Trying to convince him to write 
 an article about it but no luck so far :( Reason to switch in 
 two words : "static typing".
Yes, static typing is a main selling point. I would also consider switching to D or Go for webstuff if it was production ready/supported. But they will need to reach Java maturity to gain traction in a wider audience...
Apr 29 2014
prev sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Wednesday, 30 April 2014 at 04:42:09 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
 Digitalmars-d wrote:
 On Tue, 2014-04-29 at 22:09 +0000, Adam D. Ruppe via 
 Digitalmars-d
 wrote:
 […]
 I can just get stuff done in D in a fraction of a time it 
 takes to do even less in RoR.
This is the stuff marketing campaigns are made from. As well as informing the cabal that is this mailing list, there needs to be tweets, Facebook, G+, and proper publishing articles of people switching from RoR, Grails, Django to web.d and vibe.d and discovering (measured and guaranteed) significant performance benefits in both time to market and run time.
I have a friend who has switched to vibe.d after being Erlang Cowboy devoted user for years. Trying to convince him to write an article about it but no luck so far :( Reason to switch in two words : "static typing".
I do like dynamic typed languages, but mostly for prototyping, scripting and tiny scale projects. The type of code that we get to write at enterprise level, static typing is very valuable, specially given how management tends to enforce "write code not tests" and the skillset of certain developers across regions. Code bases being worked on with 30+ developers across multiple sites get fragile very easily. -- Paulo
Apr 30 2014
prev sibling next sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
Digitalmars-d wrote:
 Go has gained much of it's traction from provably and 
 consistently
 producing simpler, faster and more reliable systems that C, 
 C++, Python,
 etc. and getting articles about the success out there.
Python is simpler than Go for web. There is a reason for why Go is still not in production on App Engine, you end up with more convoluted code as far as I can tell. Faster, yep.
Apr 29 2014
next sibling parent reply "Paulo Pinto" <pjmlp progtools.org> writes:
On Wednesday, 30 April 2014 at 05:00:47 UTC, Ola Fosheim Grøstad
wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
 Digitalmars-d wrote:
 Go has gained much of it's traction from provably and 
 consistently
 producing simpler, faster and more reliable systems that C, 
 C++, Python,
 etc. and getting articles about the success out there.
Python is simpler than Go for web. There is a reason for why Go is still not in production on App Engine, you end up with more convoluted code as far as I can tell. Faster, yep.
Only because developers don't reach for PyPy and Cython as much as they should, rather re-writing everything from scratch and they stating how they are impressed by Go.
Apr 30 2014
parent "Mengu" <mengukagan gmail.com> writes:
On Wednesday, 30 April 2014 at 07:18:49 UTC, Paulo Pinto wrote:
 On Wednesday, 30 April 2014 at 05:00:47 UTC, Ola Fosheim Grøstad
 wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
 Digitalmars-d wrote:
 Go has gained much of it's traction from provably and 
 consistently
 producing simpler, faster and more reliable systems that C, 
 C++, Python,
 etc. and getting articles about the success out there.
Python is simpler than Go for web. There is a reason for why Go is still not in production on App Engine, you end up with more convoluted code as far as I can tell. Faster, yep.
Only because developers don't reach for PyPy and Cython as much as they should, rather re-writing everything from scratch and they stating how they are impressed by Go.
thank god i'm not the only one who thinks like that. rob pike mentioned that there are much more conversion of python / ruby developers than c / c++ developers. and as we all know the reason is the speed and there's a trade off. they're trading beauty, elegance, simplicity with ugly speed. i also think many go users are caught NIH syndrome. they are re-inventing everything. heck, they are even re-inventing nginx, redis, etc. because they are _not written_ in go. on ruby on rails side, it is fairly very easy. i've built apps with rails and i've always been happy with it. some apps used rails defaults, some apps were very customised. the thing with ror is that it is never getting in your way when you open up your editor and start building your application and that's what i look for in a web framework.
Apr 30 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 05:00 +0000, via Digitalmars-d wrote:
[…]
 Python is simpler than Go for web. There is a reason for why Go 
 is still not in production on App Engine, you end up with more 
 convoluted code as far as I can tell. Faster, yep.
I disagree. A good Python Web application would be using Flask, Bottle, Tornado, Pyramid, Django as a framework and a design and idioms to suit. A good Go Web application has a very different architecture, design and code idioms due to the use of CSP via the goroutines. I do non-HTTP networking rather than HTTP networking and end up with very different solutions to the same problem using Python and Go. If QtD were in a better state I could do a D version… -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 17:23:49 UTC, Russel Winder via 
Digitalmars-d wrote:
 Tornado, Pyramid, Django as a framework and a design and idioms
I've looked closely at Django. I find it more convenient to use smaller independent libraries inspired by Django than using the framework itself. The problem with frameworks that are supposed to support a plugin architecture is that they become complex and not very transparent. That makes debugging harder, and you need to debug because plugins don't always integrate well with each other. So at the end of the day you spend time struggling with debugging complex mechanics that you only need to support plugins. With a more nimble environment you spend less time debugging (or trying to figure out what a plugin actually does) and more time coding stuff that fits the requirements. Frameworks requires you to invest time, that can pay off, but frameworks have trouble moving with the times so… that investment does not pay off long term when you realize that you need to switch to a different framework. As an example: some of the frameworks I've looked at predated UTF-8 and contains an insane amount of code just for dealing with different character sets. The same is true for the client side. Some of the javascript frameworks contains a silly amount of code for dealing with IE6 and other browsers that you can safely ignore…
 A good Go Web application has a very different architecture, 
 design and code idioms due to the use of CSP via the goroutines.
Well, I only know Go from Google App Engine. Browse the hello-world tutorial and you'll see that the Python version is more legible (?): https://developers.google.com/appengine/docs/go/gettingstarted/introduction https://developers.google.com/appengine/docs/python/gettingstartedpython27/introduction
Apr 30 2014
parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 18:04 +0000, via Digitalmars-d wrote:
[…]
 I've looked closely at Django. I find it more convenient to use 
 smaller independent libraries inspired by Django than using the 
 framework itself.
If you have a "full stack" solution to a problem then Django does work quite well, however most of my use is far from "full stack" so Flask, Bottle, Twisted and Tornado are my "go to" (*) Python frameworks
 The problem with frameworks that are supposed to support a plugin 
 architecture is that they become complex and not very 
 transparent. That makes debugging harder, and you need to debug 
 because plugins don't always integrate well with each other. So 
 at the end of the day you spend time struggling with debugging 
 complex mechanics that you only need to support plugins. With a 
 more nimble environment you spend less time debugging (or trying 
 to figure out what a plugin actually does) and more time coding 
 stuff that fits the requirements.
For "lightweight" problems, "full stack" frameworks are a disaster. Hence the "lightweight" frameworks. Flask + SQLAlchemy is a very popular combination. I'm not sure what the D equivalent is but I guess it is vibe.d + ???. […]
 Well, I only know Go from Google App Engine. Browse the 
 hello-world tutorial and you'll see that the Python version is 
 more legible (?):
I treat GAE as an anti-pattern. (*) Are we allowed to have gotos any more since Dijkstra's letter? -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 20:00:59 UTC, Russel Winder via 
Digitalmars-d wrote:
 If you have a "full stack" solution to a problem then Django 
 does work
 quite well, however most of my use is far from "full stack" so
Depends on what "full stack" is meant to cover. I haven't found a single full-fledged forum software framework for Python, but plenty for PhP. So in the end "full stack" isn't really enough. You still end up having to integrate with "foreign" systems.
 Flask,
 Bottle, Twisted and Tornado are my "go to" (*) Python frameworks
Ok, those are so lightweight that they are very close to being libraries.
 For "lightweight" problems, "full stack" frameworks are a 
 disaster.
Yeah, but I think they are a disaster because they don't follow the times. :-) Lightweight do, well at least they are remade or forked.
 Well, I only know Go from Google App Engine. Browse the 
 hello-world tutorial and you'll see that the Python version is 
 more legible (?):
I treat GAE as an anti-pattern.
Hehe, but webapp2 + jinja2 isn't all that different from Flask and Bottle (which also can run on GAE). I am under the impression that Go for GAE is written by the Go Team? So it shouldn't be an anti-pattern… (?)
 (*) Are we allowed to have gotos any more since Dijkstra's 
 letter?
You better ask the dining philosophers.
Apr 30 2014
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 4:17 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Wednesday, 30 April 2014 at 20:00:59 UTC, Russel Winder via

 (*) Are we allowed to have gotos any more since Dijkstra's letter?
You better ask the dining philosophers.
Nah, they're too busy trying to figure out how to use their forks.
May 02 2014
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
Digitalmars-d wrote:
 This is the stuff marketing campaigns are made from.
Eh, like Jacob said later, I don't think this is a totally fair comparison cuz I'm a world class D expert but a RoR n00b, so there's naturally some difference in speed there. Of course, I doubt the gap will ever be closed, since Ruby's awfulness isn't dependent on my experience level. It's not like it will ever get static typing even if I used it all the time. It won't get faster. ActiveRecord won't get sane. But still, one person's productivity is too subjective to focus a lot on IMO.
Apr 30 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 30 April 2014 at 13:38:28 UTC, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via 
 Digitalmars-d wrote:
 This is the stuff marketing campaigns are made from.
Eh, like Jacob said later, I don't think this is a totally fair comparison cuz I'm a world class D expert but a RoR n00b, so there's naturally some difference in speed there. Of course, I doubt the gap will ever be closed, since Ruby's awfulness isn't dependent on my experience level. It's not like it will ever get static typing even if I used it all the time. It won't get faster. ActiveRecord won't get sane. But still, one person's productivity is too subjective to focus a lot on IMO.
Calculated dishonesty is healthy in a marketing campaign :p
Apr 30 2014
parent "Wyatt" <wyatt.epp gmail.com> writes:
On Wednesday, 30 April 2014 at 13:52:25 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 13:38:28 UTC, Adam D. Ruppe 
 wrote:
 But still, one person's productivity is too subjective to 
 focus a lot on IMO.
Calculated dishonesty is healthy in a marketing campaign :p
Put another way, one data point is not data but a lot of them is. Every anecdote carries some weight. And even as one person, there are probably a non-trivial number of people who think roughly the same way and would benefit from...err, from being proselytised? ;) -Wyatt
Apr 30 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-30 15:38, Adam D. Ruppe wrote:

 Of course, I doubt the gap will ever be closed, since Ruby's awfulness
 isn't dependent on my experience level. It's not like it will ever get
 static typing even if I used it all the time. It won't get faster.
 ActiveRecord won't get sane.
Ruby has gotten faster in each release. -- /Jacob Carlborg
Apr 30 2014
parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 21:06 +0200, Jacob Carlborg via Digitalmars-d
wrote:
 On 2014-04-30 15:38, Adam D. Ruppe wrote:
 
 Of course, I doubt the gap will ever be closed, since Ruby's awfulness
 isn't dependent on my experience level. It's not like it will ever get
 static typing even if I used it all the time. It won't get faster.
 ActiveRecord won't get sane.
Ruby has gotten faster in each release.
Especially if you run JRuby on the JVM :-) -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 30 2014
parent Paulo Pinto <pjmlp progtools.org> writes:
Am 30.04.2014 22:12, schrieb Russel Winder via Digitalmars-d:
 On Wed, 2014-04-30 at 21:06 +0200, Jacob Carlborg via Digitalmars-d
 wrote:
 On 2014-04-30 15:38, Adam D. Ruppe wrote:

 Of course, I doubt the gap will ever be closed, since Ruby's awfulness
 isn't dependent on my experience level. It's not like it will ever get
 static typing even if I used it all the time. It won't get faster.
 ActiveRecord won't get sane.
Ruby has gotten faster in each release.
Especially if you run JRuby on the JVM :-)
Or shell out money for an AOT compiler like RubyMotion.
Apr 30 2014
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 4/30/14, 10:38 AM, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via
 Digitalmars-d wrote:
 Of course, I doubt the gap will ever be closed, since Ruby's awfulness
 isn't dependent on my experience level. It's not like it will ever get
 static typing even if I used it all the time.
Nah, that will never happen. But you can get very close ( http://crystal-lang.org/ ), although you loose some dynamism at runtime...
Apr 30 2014
parent Paulo Pinto <pjmlp progtools.org> writes:
Am 01.05.2014 01:05, schrieb Ary Borenszweig:
 On 4/30/14, 10:38 AM, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 04:19:15 UTC, Russel Winder via
 Digitalmars-d wrote:
 Of course, I doubt the gap will ever be closed, since Ruby's awfulness
 isn't dependent on my experience level. It's not like it will ever get
 static typing even if I used it all the time.
Nah, that will never happen. But you can get very close ( http://crystal-lang.org/ ), although you loose some dynamism at runtime...
Nice to see Crystal still alive.
Apr 30 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 30/04/14 00:09, Adam D. Ruppe wrote:

 A lot of things, mostly focusing around having the compiler to help
 refactor with confidence (the importance of this really can't be
 understated) and having libraries that fit better.
I think one of the great things about Rails and Ruby is all the libraries and plugins that are available. If I want to do something, in RoR there's a big chance there's already a library for that. In D, there's a big chance I need to implement it myself.
 The speed is a nice
 bonus too, having to spend half a minute just waiting for the tests to
 run really grates me.
Yeah, it's sucks that Rails is so slow to boot. But unit tests in D suck as well. I mean, how do I run a single unit test in D? Also, my text editor (TextMate) already has support for the unit tests frameworks used in Ruby.
 But wrt libraries, ActiveRecord is unbelievably awful, for example. It
 is a bad idea from the ground up: why, oh why are we reinventing the
 database?
How do you mean? It just adds an object oriented layer on top of it. BTW, what should I use in D. I need a library that is database independent and I don't want to write SQL for the common use cases?
 erb templates are painful to use too
I prefer HAML (similar to Jade in vibe.d) but I don't think it's that bad. What do you use?
 , and so is the routing. I
 don't understand why routing isn't done automatically for the common case.
I don't know how you do you're routing but the first thing I do when generating a new Rails application is to remove the default routing. The default routing opens every public method in a controller to be a routing end point. It's a complete mess.
 The scaffolding is a pain too. Contrast to what web.d does: given a
 function signature, it automatically generates a form for it (using type
 information to select correct widgets) and can format the response in
 several forms automatically including plain text, html list, html table,
 json, xml, csv, and a custom template.
There's a plugin [1] for Rails for generating a form based on a type. I don't understand how anyone can manage without that. It can automatically respond in a couple of formats as well. By default JSON, XML and Erb template. The most basic example will look something like this: class FoosController < ApplicationController respond_to :json, :xml def index respond_with Foo.all end end
 Maybe Rails can do this stuff and I'm too much of a n00b, but the other
 experienced team members say the way we're doing it is pretty standard
 and I'm just not impressed.
Sure, it depends on what's "standard". Only using what's installed by default. Then yes, perhaps that's standard. But it's not always the best idea. At my previous work I did quite a lot different compared to the "experienced" team members.
 I can just get stuff done in D in a fraction of a time it takes to do
 even less in RoR.
You don't think that's because you're used D for quite a while and developed your own web framework. Compared to Rails where you're completely new. The biggest problem I have with D is have to do everything myself. I'm getting a bit tired of that. [1] https://github.com/plataformatec/simple_form -- /Jacob Carlborg
Apr 30 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote:
 But unit tests in D suck as well. I mean, how do I run a single 
 unit test in D?
This is common complaint I still fail to understand. I have never ever wanted to run a single unit test, why would one need it? If running all module tests at once creates problems than either module is too big or unit tests are not really unit tests.
Apr 30 2014
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 4/30/14, 6:43 AM, Dicebot wrote:
 On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote:
 But unit tests in D suck as well. I mean, how do I run a single unit
 test in D?
This is common complaint I still fail to understand. I have never ever wanted to run a single unit test, why would one need it? If running all module tests at once creates problems than either module is too big or unit tests are not really unit tests.
When I have a bug in my code I usually add a test for it so it never happens again. Because it's a bug, I might need to debug it. So I add a couple of "writefln" instead of using a debugger (it's faster and I get formatted results easier). Now, if I run all tests I will get output from all the tests, not the one I'm trying to debug. That's really annoying.
Apr 30 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig 
wrote:
 When I have a bug in my code I usually add a test for it so it 
 never happens again.

 Because it's a bug, I might need to debug it. So I add a couple 
 of "writefln" instead of using a debugger (it's faster and I 
 get formatted results easier).

 Now, if I run all tests I will get output from all the tests, 
 not the one I'm trying to debug. That's really annoying.
Output from the failing test will always be the last one in console. Pipe to tail -> profit. This sounds as pure aesthetics issue.
Apr 30 2014
next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Apr 30, 2014 at 02:25:05PM +0000, Dicebot via Digitalmars-d wrote:
 On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig wrote:
When I have a bug in my code I usually add a test for it so it never
happens again.

Because it's a bug, I might need to debug it. So I add a couple of
"writefln" instead of using a debugger (it's faster and I get
formatted results easier).

Now, if I run all tests I will get output from all the tests, not the
one I'm trying to debug. That's really annoying.
Output from the failing test will always be the last one in console. Pipe to tail -> profit. This sounds as pure aesthetics issue.
What I usually do is to be writefln at the start and end of the failing test, so I know exactly which part of the output belongs to the failure: unittest { writeln("Starting failing test"); ... // stuff writeln("debug value = %s", ...); ... // stuff writeln("End failing test"); } Then just pipe it to: sed -ne/^Starting\ failing\ test/,/^End\ failing\ test/p and you're good to go. :-) (The "End" message is there so that you're sure the failure is coming from this test, not somewhere else, and also serves as an indicator of when the problem gets fixed and it moves on to the next test.) T -- It's amazing how careful choice of punctuation can leave you hanging:
Apr 30 2014
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 4/30/14, 11:25 AM, Dicebot wrote:
 On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig wrote:
 When I have a bug in my code I usually add a test for it so it never
 happens again.

 Because it's a bug, I might need to debug it. So I add a couple of
 "writefln" instead of using a debugger (it's faster and I get
 formatted results easier).

 Now, if I run all tests I will get output from all the tests, not the
 one I'm trying to debug. That's really annoying.
Output from the failing test will always be the last one in console. Pipe to tail -> profit. This sounds as pure aesthetics issue.
That's good. What if you have tests against a database that where each take some time? I don't want to wait for the whole tests to run...
Apr 30 2014
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 14:58:20 UTC, Ary Borenszweig 
wrote:
 That's good.

 What if you have tests against a database that where each take 
 some time? I don't want to wait for the whole tests to run...
Tests with I/O are not unit tests. And built-in D feature is not called unit-or-somet-other-tests. For integration testing you need some different approach where being able to run separate cases is indeed useful. But it is not a fault of D _unit_ test design.
Apr 30 2014
prev sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 10:58 AM, Ary Borenszweig wrote:
 What if you have tests against a database that where each take some
 time? I don't want to wait for the whole tests to run...
Collapse block, [Home], [Shift]-[Down] (select), [Ctrl]-/ (comment) ;) Just FWIW, though. I'm not arguing for or against an ability to run specific unittests.
Apr 30 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/30/14, 7:18 AM, Ary Borenszweig wrote:
 On 4/30/14, 6:43 AM, Dicebot wrote:
 On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote:
 But unit tests in D suck as well. I mean, how do I run a single unit
 test in D?
This is common complaint I still fail to understand. I have never ever wanted to run a single unit test, why would one need it? If running all module tests at once creates problems than either module is too big or unit tests are not really unit tests.
When I have a bug in my code I usually add a test for it so it never happens again. Because it's a bug, I might need to debug it. So I add a couple of "writefln" instead of using a debugger (it's faster and I get formatted results easier). Now, if I run all tests I will get output from all the tests, not the one I'm trying to debug. That's really annoying.
Yah, naming unittests is key here. With names one can specify which to run/not run, regex patterns (i.e. "run only quick*") etc. -- Andrei
Apr 30 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have never ever
 wanted to run a single unit test, why would one need it? If running all
 module tests at once creates problems than either module is too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to? BTW, I would probably use the "unittest" keyword for other kinds of tests than unit tests as well. -- /Jacob Carlborg
Apr 30 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have 
 never ever
 wanted to run a single unit test, why would one need it? If 
 running all
 module tests at once creates problems than either module is 
 too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
 BTW, I would probably use the "unittest" keyword for other 
 kinds of tests than unit tests as well.
This is main problem with your expectations I think.
Apr 30 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/30/14, 12:25 PM, Dicebot wrote:
 On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have never ever
 wanted to run a single unit test, why would one need it? If running all
 module tests at once creates problems than either module is too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
*cough* std.datetime *cough* :o) One good example is networking tests - if I worked on an airplane I'd love to not test tests that need connectivity with a simple regex. Andrei
Apr 30 2014
next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 4:36 PM, Andrei Alexandrescu wrote:
 One good example is networking tests - if I worked on an airplane I'd
 love to not test tests that need connectivity with a simple regex.
The biggest thing for me has been unittests in third party libraries (hence the idiom of -version=unittest_myProjectName, but sometimes libs don't do that). Although I seem to remember being told there's a way around that, some hook into the unittest system or something.
Apr 30 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 20:36:15 UTC, Andrei Alexandrescu 
wrote:
 On 4/30/14, 12:25 PM, Dicebot wrote:
 On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg 
 wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have 
 never ever
 wanted to run a single unit test, why would one need it? If 
 running all
 module tests at once creates problems than either module is 
 too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
*cough* std.datetime *cough* :o)
Pretty much everyone agrees that std.datetime needs to be split into smaller module which was one of my original points.
 One good example is networking tests - if I worked on an 
 airplane I'd love to not test tests that need connectivity with 
 a simple regex.
Again, networking (as well as any other I/O) has no place in unit tests. Never. Supporting such kind of tests natively means designing completely new system not changing existing one. For most simple example, you can't run non-unit tests in parallel without explicit annotations from programmer (your other thread).
May 01 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 4/30/2014 1:36 PM, Andrei Alexandrescu wrote:
 One good example is networking tests - if I worked on an airplane I'd love to
 not test tests that need connectivity with a simple regex.
I am suspicious that testing networks with a unit test is an inappropriate use of unit tests. Unit tests should be testing individual functions. The "network" for those tests should be a mockup, not the actual network. A mock network: 1. can model extreme, unusual, perverse, and corner cases of networks, whereas real networks try to avoid that 2. will generate reproducible results Testing networks should be more of a system test, not a unit test.
May 03 2014
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 5/3/2014 3:32 PM, Walter Bright wrote:
 On 4/30/2014 1:36 PM, Andrei Alexandrescu wrote:
 One good example is networking tests - if I worked on an airplane I'd
 love to
 not test tests that need connectivity with a simple regex.
I am suspicious that testing networks with a unit test is an inappropriate use of unit tests. Unit tests should be testing individual functions. The "network" for those tests should be a mockup, not the actual network. A mock network: 1. can model extreme, unusual, perverse, and corner cases of networks, whereas real networks try to avoid that 2. will generate reproducible results Testing networks should be more of a system test, not a unit test.
I'm not sure mock networks can really be used for testing a client-only lib of some specific protocol. There may also be other examples. There's also the question of whether or not D's "unittest {...}" should *expect* to be limited to tests that are *technically* "unit tests". Currently, "unittest {...}" is useful for more forms of testing than just "unit" tests. I think it's debatable whether we want kill off those uses without offering a comparable alternative with reasonable migration.
May 03 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/3/2014 6:57 PM, Nick Sabalausky wrote:
 I'm not sure mock networks can really be used for testing a client-only lib of
 some specific protocol. There may also be other examples.

 There's also the question of whether or not D's "unittest {...}" should
*expect*
 to be limited to tests that are *technically* "unit tests". Currently,
"unittest
 {...}" is useful for more forms of testing than just "unit" tests. I think it's
 debatable whether we want kill off those uses without offering a comparable
 alternative with reasonable migration.
I'm not suggesting killing off anything. I'm suggesting it may not be good practice to use unit tests for testing actual networks.
May 03 2014
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 03 May 2014 19:36:53 -0700
Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 On 5/3/2014 6:57 PM, Nick Sabalausky wrote:
 I'm not sure mock networks can really be used for testing a
 client-only lib of some specific protocol. There may also be other
 examples.

 There's also the question of whether or not D's "unittest {...}"
 should *expect* to be limited to tests that are *technically* "unit
 tests". Currently, "unittest {...}" is useful for more forms of
 testing than just "unit" tests. I think it's debatable whether we
 want kill off those uses without offering a comparable alternative
 with reasonable migration.
I'm not suggesting killing off anything. I'm suggesting it may not be good practice to use unit tests for testing actual networks.
I'd write unit tests which talked to sockets on the same computer if that was what was required to test a particular function, but I would definitely consider it bad practice to have a unit test try to talk to anything on a separate computer. Now, if you're using unittest blocks for something other than unit tests, then I guess that that could be fine, though I question that it's good practice to use unittest blocks for other purposes. Regardless, unittest blocks don't really put any restrictions on what kind of code can go in them, and I'd prefer that that stay the case. The discussion on parallelizing unit tests threatens that on some level, but as long as we have the means to mark unittest blocks in some manner that tells the test runner not to run them in parallel with any other unittest blocks, then I think that we should be fine on that front. - Jonathan M Davis
May 03 2014
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 5/4/2014 12:34 AM, Jonathan M Davis via Digitalmars-d wrote:
 Regardless, unittest blocks don't really put any restrictions on what kind of
 code can go in them, and I'd prefer that that stay the case. The discussion
 on parallelizing unit tests threatens that on some level, but as long as we
 have the means to mark unittest blocks in some manner that tells the test
 runner not to run them in parallel with any other unittest blocks, then I
 think that we should be fine on that front.
Yes, this.
May 04 2014
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 30 April 2014 at 19:25:40 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg 
 wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have 
 never ever
 wanted to run a single unit test, why would one need it? If 
 running all
 module tests at once creates problems than either module is 
 too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
The compilation time is often more of a problem than the runtime.
May 01 2014
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/1/14, 3:50 AM, John Colvin wrote:
 On Wednesday, 30 April 2014 at 19:25:40 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have never ever
 wanted to run a single unit test, why would one need it? If running all
 module tests at once creates problems than either module is too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
The compilation time is often more of a problem than the runtime.
That's the case for phobos. -- Andrei
May 01 2014
prev sibling parent reply "Atila Neves" <atila.neves gmail.com> writes:
On Thursday, 1 May 2014 at 10:50:12 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 19:25:40 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 19:08:15 UTC, Jacob Carlborg 
 wrote:
 On 2014-04-30 11:43, Dicebot wrote:

 This is common complaint I still fail to understand. I have 
 never ever
 wanted to run a single unit test, why would one need it? If 
 running all
 module tests at once creates problems than either module is 
 too big or
 unit tests are not really unit tests.
Why would I run more tests than I have to?
Because you hardly notice difference between 0.1 and 0.5 seconds
The compilation time is often more of a problem than the runtime.
For me it's the output. I don't want to see the output of other tests when I'm debugging a failure. Atila
May 03 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-05-03 21:52, Atila Neves wrote:

 For me it's the output. I don't want to see the output of other
 tests when I'm debugging a failure.
That's a good point. -- /Jacob Carlborg
May 04 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 21:08 +0200, Jacob Carlborg via Digitalmars-d
wrote:
[…]
 Why would I run more tests than I have to? BTW, I would probably use the 
 "unittest" keyword for other kinds of tests than unit tests as well.
This cannot be a good idea. If the block says unittest then it contains unit tests, not integration tests or system tests, just unit tests. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 30 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-30 22:11, Russel Winder via Digitalmars-d wrote:

 This cannot be a good idea. If the block says unittest then it contains
 unit tests, not integration tests or system tests, just unit tests.
Then we need to come up with a separate framework for doing all other kinds of tests. -- /Jacob Carlborg
May 01 2014
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 5/1/14, 6:58 AM, Jacob Carlborg wrote:
 On 2014-04-30 22:11, Russel Winder via Digitalmars-d wrote:

 This cannot be a good idea. If the block says unittest then it contains
 unit tests, not integration tests or system tests, just unit tests.
Then we need to come up with a separate framework for doing all other kinds of tests.
Yes. And then you need two different commands to check if the system works. And if you want, for example, coverage analysis I wonder how you'd do that... That can't be good.
May 01 2014
parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 1 May 2014 at 12:17:56 UTC, Ary Borenszweig wrote:
 On 5/1/14, 6:58 AM, Jacob Carlborg wrote:
 On 2014-04-30 22:11, Russel Winder via Digitalmars-d wrote:

 This cannot be a good idea. If the block says unittest then 
 it contains
 unit tests, not integration tests or system tests, just unit 
 tests.
Then we need to come up with a separate framework for doing all other kinds of tests.
Yes. And then you need two different commands to check if the system works. And if you want, for example, coverage analysis I wonder how you'd do that... That can't be good.
Two commands effectively. `rdmd -unittest` for development cycle of single module and `make test` to verify everything after feature/bugfix is completed. This is what I tend to do with existing tools (by splitting higher level tests in separate applications), adding some in-language support will just make intention a bit more clear.
May 01 2014
prev sibling parent reply "Atila Neves" <atila.neves gmail.com> writes:
On Thursday, 1 May 2014 at 09:58:32 UTC, Jacob Carlborg wrote:
 On 2014-04-30 22:11, Russel Winder via Digitalmars-d wrote:

 This cannot be a good idea. If the block says unittest then it 
 contains
 unit tests, not integration tests or system tests, just unit 
 tests.
Then we need to come up with a separate framework for doing all other kinds of tests.
This is why I started to learn Cucumber. Atila
May 03 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-05-03 21:51, Atila Neves wrote:

 This is why I started to learn Cucumber.
Cucumber is for acceptance tests. There are also functional and integration tests. -- /Jacob Carlborg
May 04 2014
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2014-05-04 at 13:44 +0200, Jacob Carlborg via Digitalmars-d
wrote:
 On 2014-05-03 21:51, Atila Neves wrote:
 
 This is why I started to learn Cucumber.
Cucumber is for acceptance tests. There are also functional and integration tests.
We could get into bikeshedding here,… Cucumber is really for supporting BDD. These include functional and integration tests as well as some varieties of acceptance test. It doesn't just have acceptance tests. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
May 04 2014
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 3:14 AM, Jacob Carlborg wrote:
 There's a plugin [1] for Rails for generating a form based on a type. I
 don't understand how anyone can manage without that. It can
 automatically respond in a couple of formats as well. By default JSON,
 XML and Erb template. The most basic example will look something like this:
Automatic forms generated from a type are nice for quick-n-dirty stuff, but I find they tend to work against (or at least be much less useful for) the tweaking and customization usually needed in public-facing production sites. So I started doing it in reverse: Instead of defining the form in the server-side code and then awkwardly trying to make it generate the HTML I want, I just define the form in HTML. (Or rather, in an HTML template that's still more-or-less valid HTML, with a few additional non-standard tags to help with metadata like "how to validate this field"). Then I use Adam's dom.d (in non-strict mode) to read the HTML form template (preserving the templating stuff), and automatically infer everything I need to automate the form's behavior (and to strip out the non-standard metadata I added). I've been pretty happy with that so far. It combines the DRY simplicity of "define a form in ONE place and it 'just works'" with the full power and control of hand-written HTML. What I really need to do is fully de-entange that stuff from my cluttered mess of a homemade web framework <https://github.com/Abscissa/SemiTwistWeb> and release as a separate cleaned-up lib.
Apr 30 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 12:26:06 UTC, Nick Sabalausky 
wrote:
 Automatic forms generated from a type are nice for 
 quick-n-dirty stuff, but I find they tend to work against (or 
 at least be much less useful for) the tweaking and 
 customization usually needed in public-facing production sites.
Aye, I rarely use my automatic forms on live sites either.... but they are really nice for backend CRUD stuff or a quick-n-dirty first-draft. Sometimes though, I can get away with just modifying an automatic form and kinda want to make web.d 2.0 better at that.
 Instead of defining the form in the server-side code and then 
 awkwardly trying to make it generate the HTML I want, I just 
 define the form in HTML. (Or rather, in an HTML template that's 
 still more-or-less valid HTML, with a few additional 
 non-standard tags to help with metadata like "how to validate 
 this field").
Yes, rox rox rox. This is what my html.d originally was for btw, expanding non-standard tags. Many of them are obsolete now tho, I use html5 attributes instead. Of course, html.d also includes other cool stuff like CSS expansion and JS foreach macros too, as we fairly recently talked about.
 Then I use Adam's dom.d (in non-strict mode) to read the HTML 
 form template (preserving the templating stuff)
I use strict mode for that stuff, keep in mind strict mode is about well-formedness, not validation. So it accepts custom tags and attributes easily enough.
Apr 30 2014
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 10:53 AM, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 12:26:06 UTC, Nick Sabalausky wrote:

 Then I use Adam's dom.d (in non-strict mode) to read the HTML form
 template (preserving the templating stuff)
I use strict mode for that stuff, keep in mind strict mode is about well-formedness, not validation. So it accepts custom tags and attributes easily enough.
Well, I've been using mustache-d as my main templating engine, which is just a general text preprocessor (Although I'm kinda eyeing that other text preprocessor that uses actual D code). IIRC, I think there were some cases where the my templates involved some non-well-formedness that the DOM's non-strict mode was perfectly happy with. Whatever it was, I'm sure there was *something* I was doing that strict mode was tripping up on. May have been an old version of the DOM, too. Granted there are still things I have to refrain from doing in my HTML form templates because it would violate well-formedness *too much* even for an ultra-relaxed HTML DOM. But those cases always have other (arguably more sanitary) ways to accomplish the same thing.
Apr 30 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 16:02:25 UTC, Nick Sabalausky 
wrote:
 Well, I've been using mustache-d as my main templating engine, 
 which is just a general text preprocessor (Although I'm kinda 
 eyeing that other text preprocessor that uses actual D code).
ah, I see. BTW, fun fact: dom.d can understand ASP and PHP style tags. You need to set a special callback or call enableAddingSpecialTagsToDom() before parse, (The latter will also enable storing comments, <! stuff> and <?stuff>) but then it will work. I did that to enable dual-use templates that have some PHP code too. But it might be interesting to use for template stuff too... BTW (ok this whole post is turning out to be a series of BTWs), web.d also has a template function that is dom-aware which I think is potentially very interesting. Like it could see <span>{$foo}</span> and be aware to add a class to that span or something. Or it could automatically wrap variables in spans iff that makes sense in the html context. Stuff I've never really used despite writing this some time ago... but I still think there's some potential to all this.
 Granted there are still things I have to refrain from doing in 
 my HTML form templates because it would violate well-formedness 
 *too much* even for an ultra-relaxed HTML DOM. But those cases 
 always have other (arguably more sanitary) ways to accomplish 
 the same thing.
yea
Apr 30 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote:
 I think one of the great things about Rails and Ruby is all the 
 libraries and plugins that are available. If I want to do 
 something, in RoR there's a big chance there's already a 
 library for that. In D, there's a big chance I need to 
 implement it myself.
I like implementing things myself :P That's the question I dread most at meetings now: "is there a gem for this?" idk, in the time it takes to search for and evaluate third party code, I could have just written it myself. Especially since libraries almost always need some kind of customization for our specific case anyway! There's a few exceptions where something is hard to write, but most things just aren't that hard.
 But unit tests in D suck as well.
A big difference though is the compiler helps you a lot in D. In Ruby, for example, the main reason we use the unit tests (so far) is to help ensure consistency after refactoring something. It catchings things like a renaming we missed, or a removed method still in use. In D, you just recompile and those things are found almost instantly without needing to actually run any code.
 How do you mean? It just adds an object oriented layer on top 
 of it.
They deliberately avoid the most important parts of a relational database: http://guides.rubyonrails.org/migrations.html "The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used." ORM is something I only like in very small quantities, but ActiveRecord uses it for *everything*, well, except for the things it doesn't even support. The problem here is one of encapsulation and of correctness. If something bypasses the model - which is required for tasks the library doesn't even support and also likely to happen if there's a second app using the data - all kinds of stuff can get in there that is bad. You also have problems like race conditions: account = BankAccount.find(1) account.balance -= 10 account.save! What if two of those run concurrently? I searched the web quickly for this and haven't found a good answer yet... Then, with referential integrity, the docs suggest DIY or getting some third party gem, because their godawful library doesn't really support it. The best it does is offer you a square wheel with the dependent thing. Stupid stupid stupid. When you actually use the database as it is intended, it takes care of these things for you with very easy syntax that works across business logic languages. Nothing new to learn there.
 BTW, what should I use in D. I need a library that is database 
 independent and I don't want to write SQL for the common use 
 cases?
idk, I use my database.d which has a little bit of overlap with what active record does, but since I generally see ORM as being a nasty anti-pattern and horribly leaky abstraction, I didn't go far with it. There's really nothing to fear with writing SQL, except the cases where the language sucks. (UPDATE and INSERT being so different, and the solutions being different for the various vendors, ugh. That's why I made my DataObject, it gathers the changes together then issues one of those commands. It can also be gotten from a query, making it a kind of simple active record: auto obj = mysql.queryDataObject("select * from foo limit 1").front; obj.whatever = "something"; obj.commitChanges(); // calls UPDATE foo SET whatever='something' WHERE id = ? which also works on joined queries on MySQL btw and offers easy support for multiple primary keys or ones not named "id" (as an argument to commitChanges), something active record as far as i can tell doesn't even try to do, but it doesn't try to fetch child objects or anything like that. I have considered adding child object fetching, but I don't really see the need, it is easy to write a method that does that if you want to.)
 I prefer HAML (similar to Jade in vibe.d) but I don't think 
 it's that bad. What do you use?
The ruby thing looks like this <span class="foo"><%= some_value %></span>. For my D stuff, I have two options: 1) create the HTML right in D using dom.d. I like to use this for objects that know how to format themselves and output strictly semantic XML/HTML. The visual styling is then done with CSS. This works better than you might expect! 2) web.d also has a fairly simple replacement system too: <span class="foo">{$some_value}</span> it also supports inserting partials <div html-from="{$dynamic_html}"></div> or <include partial="foo" />, though the include thing takes a wee bit of helper code from the app because it needs to find the html somewhere. And the variable replacement can be piped: {$some_count|plural user users} for example, which is kinda cool. It does NOT support intertwined code. Other things are done with attributes, such as class="if-logged-in" or <ul from="data_thing" /> (infinitely extensible with the server-side DOM).
 I don't know how you do you're routing but the first thing I do 
 when generating a new Rails application is to remove the 
 default routing. The default routing opens every public method 
 in a controller to be a routing end point. It's a complete mess.
It looks like this root "home#index" get "/users/login", to: "users#login" namespace :admin do resources :users do resources :children end end and so on. It isn't awful (especially now that I get what they mean by "resources"), but my web.d rarely uses explicit routing at all, it figures it out automatically by the names, protection level, and types of child members.
 There's a plugin [1] for Rails for generating a form based on a 
 type. I don't understand how anyone can manage without that.
thx, I'll take a gander.
 It can automatically respond in a couple of formats as well. By 
 default JSON, XML and Erb template. The most basic example will 
 look something like this:
Responding with json, xml, and html Just Work with web.d, it figures it out from the static type of the function return value.
 You don't think that's because you're used D for quite a while 
 and developed your own web framework. Compared to Rails where 
 you're completely new.
Yes, obviously that's some of it, but there's other things that I don't expect to change, especially things like runtime errors for what the D compiler would catch. I had to rename a thing last night. Took two hours to do the db migrations and then rename the classes and update all the files. I'm still not completely sure I did it right too! I've done similar things in D in about 5 minutes, the compiler catches everything so I have confidence.
 The biggest problem I have with D is have to do everything 
 myself. I'm getting a bit tired of that.
i love that, different strokes i guess.
Apr 30 2014
next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 11:04 AM, Adam D. Ruppe wrote:
 A big difference though is the compiler helps you a lot in D. In Ruby,
 for example, the main reason we use the unit tests (so far) is to help
 ensure consistency after refactoring something. It catchings things like
 a renaming we missed, or a removed method still in use.
This has a lot to do with why I don't buy the common argument that dynamic languages are all about "just getting shit done". Anytime I use them, they just create more work for me. Writing more sanity checks. More hours debugging. More work to optimize hotspots. More time figuring out Tracebacks I'm getting from code I didn't even write or from tools I'm simply trying to install. Etc.
 In D, you just recompile and those things are found almost instantly
 without needing to actually run any code.
Gotta love it :)
Apr 30 2014
next sibling parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 12:41 -0400, Nick Sabalausky via Digitalmars-d
wrote:
[…]
 This has a lot to do with why I don't buy the common argument that 
 dynamic languages are all about "just getting shit done".
Interesting use of the word shit. I tend to find that the average programmer produces shit code in whatever language they use. This is a sad reflection on the whole of computing.
 Anytime I use them, they just create more work for me. Writing more 
 sanity checks. More hours debugging. More work to optimize hotspots. 
 More time figuring out Tracebacks I'm getting from code I didn't even 
 write or from tools I'm simply trying to install. Etc.
Using a static language mindset when working with a dynamic language has this effect. Likewise the reverse, using a dynamic language mindset with a static language. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 30 2014
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 16:42:00 UTC, Nick Sabalausky 
wrote:
 Anytime I use them, they just create more work for me.
def. I like them in small quantities - heck, I'm written dynamic types and scripting languages for D! But they cause me pain pretty quickly.
Apr 30 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-30 17:04, Adam D. Ruppe wrote:

 I like implementing things myself :P

 That's the question I dread most at meetings now: "is there a gem for
 this?" idk, in the time it takes to search for and evaluate third party
 code, I could have just written it myself. Especially since libraries
 almost always need some kind of customization for our specific case anyway!
I don't agree with this.
 A big difference though is the compiler helps you a lot in D. In Ruby,
 for example, the main reason we use the unit tests (so far) is to help
 ensure consistency after refactoring something. It catchings things like
 a renaming we missed, or a removed method still in use.
Then you're not using unit tests correctly ;)
 In D, you just recompile and those things are found almost instantly
 without needing to actually run any code.
Yeah, sometimes it would be nice with static typing.
 They deliberately avoid the most important parts of a relational database:

 http://guides.rubyonrails.org/migrations.html

 "The Active Record way claims that intelligence belongs in your models,
 not in the database. As such, features such as triggers or foreign key
 constraints, which push some of that intelligence back into the
 database, are not heavily used."
I don't really agree with that. Although I'm not a fan of store procedures/functions in the database. But I don't mind foreign key constraints. We used that at my previous work. Via a gem :)
 ORM is something I only like in very small quantities, but ActiveRecord
 uses it for *everything*, well, except for the things it doesn't even
 support.

 The problem here is one of encapsulation and of correctness. If
 something bypasses the model - which is required for tasks the library
 doesn't even support and also likely to happen if there's a second app
 using the data - all kinds of stuff can get in there that is bad.

 You also have problems like race conditions:

 account = BankAccount.find(1)
 account.balance -= 10
 account.save!
I think most Rails application are run single threaded. But with multiple processes instead.
 What if two of those run concurrently? I searched the web quickly for
 this and haven't found a good answer yet...

 Then, with referential integrity, the docs suggest DIY or getting some
 third party gem, because their godawful library doesn't really support
 it. The best it does is offer you a square wheel with the dependent
 thing. Stupid stupid stupid.
All libraries have positive and negative sides.
 idk, I use my database.d which has a little bit of overlap with what
 active record does, but since I generally see ORM as being a nasty
 anti-pattern and horribly leaky abstraction, I didn't go far with it.
Using a random D module for this doesn't feel very comfortable, no offense. No documentation, no way to find examples and so on.
 There's really nothing to fear with writing SQL, except the cases where
 the language sucks.
ActiveRecord will hide all the ugliness of SQL. Properly escape values, to type conversions, time zone conversions and so on. It's also database independent.
 (UPDATE and INSERT being so different, and the
 solutions being different for the various vendors, ugh. That's why I
 made my DataObject, it gathers the changes together then issues one of
 those commands. It can also be gotten from a query, making it a kind of
 simple active record:

 auto obj = mysql.queryDataObject("select * from foo limit 1").front;
 obj.whatever = "something";
 obj.commitChanges(); // calls UPDATE foo SET whatever='something' WHERE
 id = ?

 which also works on joined queries on MySQL btw and offers easy support
 for multiple primary keys or ones not named "id" (as an argument to
 commitChanges), something active record as far as i can tell doesn't
 even try to do, but it doesn't try to fetch child objects or anything
 like that.

 I have considered adding child object fetching, but I don't really see
 the need, it is easy to write a method that does that if you want to.)

 I prefer HAML (similar to Jade in vibe.d) but I don't think it's that
 bad. What do you use?
The ruby thing looks like this <span class="foo"><%= some_value %></span>. For my D stuff, I have two options: 1) create the HTML right in D using dom.d. I like to use this for objects that know how to format themselves and output strictly semantic XML/HTML. The visual styling is then done with CSS. This works better than you might expect!
Are you using some kind of proxy for this or are you pushing back the view layer to the model?
 2) web.d also has a fairly simple replacement system too:

 <span class="foo">{$some_value}</span>

 it also supports inserting partials

 <div html-from="{$dynamic_html}"></div> or <include partial="foo" />,
 though the include thing takes a wee bit of helper code from the app
 because it needs to find the html somewhere.
Well, that's the same as in Rails. The HAML version would be: partial is just a template prefixed with an underscore. It fill find it relative to the controller's view directory.
 And the variable replacement can be piped: {$some_count|plural user
 users} for example, which is kinda cool.
I'm not sure I understand this piping.
 It does NOT support intertwined code. Other things are done with
 attributes, such as class="if-logged-in" or <ul from="data_thing" />
 (infinitely extensible with the server-side DOM).
What do you mean with "intertwined code"?
 It looks like this

    root "home#index"

    get "/users/login", to: "users#login"

    namespace :admin do
      resources :users do
        resources :children
      end
    end


 and so on. It isn't awful (especially now that I get what they mean by
 "resources"), but my web.d rarely uses explicit routing at all, it
 figures it out automatically by the names, protection level, and types
 of child members.
In Rails that would be: match ":controller(/:action(/:id))" So "/foo/bar/1" would route to "bar" action in the FooController with "1" assigned as the "id" parameter in "params". Only works with public methods. I really hate this. It quickly becomes a big mess. You can also do a catch all route: match "*path" => "home#page_not_found"
 Responding with json, xml, and html Just Work with web.d, it figures it
 out from the static type of the function return value.
In my experience it's rarely so easy. Most of the time I need to do some customization of the format anyway so the built-in formatting isn't suitable.
 Yes, obviously that's some of it, but there's other things that I don't
 expect to change, especially things like runtime errors for what the D
 compiler would catch.
Yes, sure.
 i love that, different strokes i guess.
I don't mind it but sometimes I just want to get some work done. I mean, I've started out (or planed to) with some project in D but then I needed to create all the support libraries and tools so I've almost forgot what I was going to do in the first place. I want to use Sass, CoffeeScript and HAML. But I don't want to write three compilers just to do some web development. -- /Jacob Carlborg
Apr 30 2014
next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 3:53 PM, Jacob Carlborg wrote:
 On 2014-04-30 17:04, Adam D. Ruppe wrote:
 You also have problems like race conditions:

 account = BankAccount.find(1)
 account.balance -= 10
 account.save!
I think most Rails application are run single threaded. But with multiple processes instead.
Aren't you talking about databases? Single-threading won't save you from races there unless the DBMS itself is single-threaded (which would be a pretty undesirable DBMS). Or does the ORM above automatically lock the row/table behind-the-scenes?
Apr 30 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-04-30 22:36, Nick Sabalausky wrote:

 Aren't you talking about databases? Single-threading won't save you from
 races there unless the DBMS itself is single-threaded (which would be a
 pretty undesirable DBMS).
Are you referring to if one process executes line 1 while another executes line 2? I don't see how ActiveRecord make this any worse.
 Or does the ORM above automatically lock the row/table behind-the-scenes?
It does saves in transactions but I don't think it locks. -- /Jacob Carlborg
May 01 2014
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 19:53:53 UTC, Jacob Carlborg wrote:
 I don't really agree with that. Although I'm not a fan of store 
 procedures/functions in the database. But I don't mind foreign 
 key constraints. We used that at my previous work. Via a gem :)
Yeah, foreign keys are really an absolute must. So are uniqueness constraints. Rails can kinda do these, but in its own reinvented ways that don't actually hit the DB (at least not without add on gems) I also find myself really missing outer joins and views.
 I think most Rails application are run single threaded. But 
 with multiple processes instead.
That doesn't change the race condition because the database is still shared across those processes. With a regular SQL query, the database guarantees consistent, atomic operations in the DB engine itself, but with active record pattern, you give that up... while still having the shared data. It was a thing like this that recently took a bitcoin exchange down. Literally the textbook example of concurrency, but most these modern newfangled frameworks get it wrong.
 Using a random D module for this doesn't feel very comfortable, 
 no offense. No documentation, no way to find examples and so on.
Yeah, I wrote these for myself and put them on the web just in case somebody else finds them useful, but it is really a take-it-or-leave-it thing to me. Even in my book when I talked about some of these libs, I focused on lessons learned when writing them more than the actual usage - my thought is then maybe people can do their own thing instead of downloading my stuff and using it straight up.
 ActiveRecord will hide all the ugliness of SQL.
It also hides all the beauty of it :(
 Properly escape values
If you're escaping values, unless you're writing some low level database library, you're almost certainly doing it wrong. I agree that using raw SQL with something like the PHP4 method of string concatenation is a huge pain and awful, as well as inefficient and insecure. But that's also the wrong way to do it and any non-crippled database API or library offers ways to separate the sql code and data cleanly and easily.
 Are you using some kind of proxy for this or are you pushing 
 back the view layer to the model?
CSS is the view in that scenario. The HTML the object returns is just its fields wrapped up in tags and classes. Works really well, for my last big job, the designer worked almost exclusively in CSS and we got a lot of stuff done.
 I'm not sure I understand this piping.
It calls functions on the variable. So like {$foo|capitalize} would be kinda like <%= capitalize(foo) %>. The plural example uses arguments to the function too so we can customize the words if it is plural or no.
 What do you mean with "intertwined code"?
<html><% some ruby here %></html> I hate that stuff, especially when the view starts doing implicit database queries! Defeats the whole point of MVC separation if you ask me.
 You can also do a catch all route:

 match "*path" => "home#page_not_found"
Aye, web.d calls a method called catchAll for those too.
 I don't mind it but sometimes I just want to get some work 
 done. I mean, I've started out (or planed to) with some project 
 in D but then I needed to create all the support libraries and 
 tools so I've almost forgot what I was going to do in the first 
 place.
meh, with my libs, they might not be accessible to others, being poorly documented and all, but I know them and have used them for almost everything that's come up over the years. So for me, getting work done means spending an hour using D instead of days searching the web for some gem that won't even work right anyway.
Apr 30 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-04-30 22:38, Adam D. Ruppe wrote:

 Yeah, foreign keys are really an absolute must. So are uniqueness
 constraints. Rails can kinda do these, but in its own reinvented ways
 that don't actually hit the DB (at least not without add on gems)
Rails unique constraints do hit the DB, but they can be painfully slow. It's usually faster to let the DB handle it and handle the exception in Ruby.
 I also find myself really missing outer joins and views.
For outer joins: 1. You can always use raw SQL, also in combination with ActiveRecord Post.joins(:comments).joins("outer join foos on foos.post_id = posts.id").where(title: "bar") 2. My preferred choice, using Squeel [1] (another gem). With Squeel the above would look like this: Post.joins(:comments).joins{ foos.outer }.where(title: "bar") It also supports queries like this: Post.where{ |q| q.id >= 3 } For views you can use raw SQL in the migration to create the view. Then it behaves just like a regular table. ActiveRecord won't know the difference. At my previous work we used the SchemaPlus [3] gem. It supports foreign keys, views and indexes.
 That doesn't change the race condition because the database is still
 shared across those processes. With a regular SQL query, the database
 guarantees consistent, atomic operations in the DB engine itself, but
 with active record pattern, you give that up... while still having the
 shared data.
I'm not sure I understand. ActiveRecord does regular SQL queries. The example you wrote: account = BankAccount.find(1) account.balance -= 10 account.save! Are you referring to if one process executes line 1 and another line 2?
 It also hides all the beauty of it :(

 Properly escape values
If you're escaping values, unless you're writing some low level database library, you're almost certainly doing it wrong.
I don't know how other libraries do it these days but last time I didn't use ActiveRecord it looked something like this: query("select * from foo where name = ?", "foobar"); BTW, this is still how you need to do it in ActiveRecord when needing something more than the equal operator. It was quite similar in Rails 2 as well. Rails 3 and later makes it a bit better. Very ugly. All values are far to the right and the query is to the left. It's get a quick overview of which values go where. Therefore I prefer Squeel as soon I need to do something more advanced than the equal operator: Foo.where{ |q| q.size >= 4 } You can also use SQL functions: Foo.where{ |q| q.created_at == q.getdate() }
 CSS is the view in that scenario. The HTML the object returns is just
 its fields wrapped up in tags and classes. Works really well, for my
 last big job, the designer worked almost exclusively in CSS and we got a
 lot of stuff done.
I never get that working. The HTML always need to change when the design changes.
 It calls functions on the variable. So like {$foo|capitalize} would be
 kinda like <%= capitalize(foo) %>. The plural example uses arguments to
 the function too so we can customize the words if it is plural or no.
Ah, I see.
 <html><% some ruby here %></html>

 I hate that stuff, especially when the view starts doing implicit
 database queries! Defeats the whole point of MVC separation if you ask me.
That's useful for looping and if-statements. I also sometimes but a variable there at the top. In Haml: - posts.each do |post| %h3= post.title .body= post.body - if current_url == post_url(post) = post.title - else = link_to post.title, post This would of course be better handled with a partial and a view helper. Yeah, I agree that it's ugly with database queries in the view. But it's very easy to end up with something like this, instead of the above: - Post.all.each do |post| Queries in the view can be good, it depends on how you look at it. If you write the query in the controller and then access the result in the view, the query will be executed in the view because since Rails 3 queries are lazy. The advantage of this is the you can stream out the response [2].
 meh, with my libs, they might not be accessible to others, being poorly
 documented and all, but I know them and have used them for almost
 everything that's come up over the years. So for me, getting work done
 means spending an hour using D instead of days searching the web for
 some gem that won't even work right anyway.
For me it's the same with Rails. I know Rails and know a lot of useful gems. [1] https://github.com/activerecord-hackery/squeel [2] http://asciicasts.com/episodes/266-http-streaming [3] https://github.com/lomba/schema_plus -- /Jacob Carlborg
May 01 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 1 May 2014 at 10:44:42 UTC, Jacob Carlborg wrote:
 On 2014-04-30 22:38, Adam D. Ruppe wrote:
 I also find myself really missing outer joins and views.
For outer joins: 1. You can always use raw SQL, also in combination with ActiveRecord Post.joins(:comments).joins("outer join foos on foos.post_id = posts.id").where(title: "bar") 2. My preferred choice, using Squeel [1] (another gem). With Squeel the above would look like this: Post.joins(:comments).joins{ foos.outer }.where(title: "bar")
You can also use the built-in `includes()`, which does a LEFT OUTER JOIN: Post.includes(:comments).where(comments: {title: "bar"}) (It also eager-loads the comments, but this is usually desired anyway, because an OUTER JOIN doesn't make sense if you're not going to use the joined records.)
May 01 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-05-01 15:54, "Marc Schütz" <schuetzm gmx.net>" wrote:

 You can also use the built-in `includes()`, which does a LEFT OUTER JOIN:

      Post.includes(:comments).where(comments: {title: "bar"})

 (It also eager-loads the comments, but this is usually desired anyway,
 because an OUTER JOIN doesn't make sense if you're not going to use the
 joined records.)
The SQL code "includes" generates is unspecified. Sometimes it can do an extra "select" instead of a "join". -- /Jacob Carlborg
May 01 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 1 May 2014 at 18:35:40 UTC, Jacob Carlborg wrote:
 On 2014-05-01 15:54, "Marc Schütz" <schuetzm gmx.net>" wrote:

 You can also use the built-in `includes()`, which does a LEFT 
 OUTER JOIN:

     Post.includes(:comments).where(comments: {title: "bar"})

 (It also eager-loads the comments, but this is usually desired 
 anyway,
 because an OUTER JOIN doesn't make sense if you're not going 
 to use the
 joined records.)
The SQL code "includes" generates is unspecified. Sometimes it can do an extra "select" instead of a "join".
You're probably right. I thought that changed in a recent release, but can't find it anymore.
May 01 2014
parent Jacob Carlborg <doob me.com> writes:
On 01/05/14 21:55, "Marc Schütz" <schuetzm gmx.net>" wrote:

 You're probably right. I thought that changed in a recent release, but
 can't find it anymore.
I don't know. I wouldn't trust it. It's the behavior in Rails 3. I haven't used Rails 4 yet. -- /Jacob Carlborg
May 02 2014
prev sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 30 April 2014 at 15:04:53 UTC, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg 
 wrote:
 I think one of the great things about Rails and Ruby is all 
 the libraries and plugins that are available. If I want to do 
 something, in RoR there's a big chance there's already a 
 library for that. In D, there's a big chance I need to 
 implement it myself.
I like implementing things myself :P That's the question I dread most at meetings now: "is there a gem for this?" idk, in the time it takes to search for and evaluate third party code, I could have just written it myself. Especially since libraries almost always need some kind of customization for our specific case anyway! There's a few exceptions where something is hard to write, but most things just aren't that hard.
I agree with this, but with a caveat: The valuable work in a 3rd party lib is more often the design than the body of the implementation. Designing a good API and general design for a library requires experience and perspective that I don't have in most problem spaces, but a quick bit of reading and the internals are often trivial to reproduce. I think this is particularly relevant in D; Implementation is made easy, but the flexibility available makes the design stage especially important. That is not to say that it's harder to make good designs with D, more that it's feasible to make *even better* designs if you have the expertise and time.
May 01 2014
prev sibling parent reply "brad clawsie" <brad b7j0c.org> writes:
On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote:

 I think one of the great things about Rails and Ruby is all the 
 libraries and plugins that are available. If I want to do 
 something, in RoR there's a big chance there's already a 
 library for that. In D, there's a big chance I need to 
 implement it myself.
this has been the fundamental issue for me. its not just missing libs, its libs that are surfaced via a C-binding, which in my limited experience have been difficult to use and make portability hard. I think D is a superior language to Go, but Go has a very complete SDK and its all written in Go, so I don't have to worry about chasing down native libs to install. brad
May 02 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-05-02 19:25, brad clawsie wrote:

 this has been the fundamental issue for me. its not just missing libs,
 its libs that are surfaced via a C-binding, which in my limited
I've had problems with ImageMagick, basically every time. But that's the only one I can think of, at least for now. -- /Jacob Carlborg
May 04 2014
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/29/2014 10:41 AM, James wrote:
 I have a friend that is a web developer. I, however want to collaborate
 with him, so I am trying to get him to learn D. I don't know how to
 persuade him! How can D be used to greatly assist an HTML5/JavaScript
 web developer? I decided to go here to get some good answers. How can D
 be used to interopt with modern web development?
Show him forum.dlang.org (written in D) and point out that modern HTML5/JS sites are freaking horrid. </admitted-curmudgeon>
Apr 29 2014
parent reply "JN" <666total wp.pl> writes:
On Tuesday, 29 April 2014 at 15:28:00 UTC, Nick Sabalausky wrote:
 Show him forum.dlang.org (written in D) and point out that 
 modern HTML5/JS sites are freaking horrid. 
 </admitted-curmudgeon>
forum.dlang.org is written in HTML/JS too.
Apr 29 2014
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/29/2014 3:48 PM, JN wrote:
 On Tuesday, 29 April 2014 at 15:28:00 UTC, Nick Sabalausky wrote:
 Show him forum.dlang.org (written in D) and point out that modern
 HTML5/JS sites are freaking horrid. </admitted-curmudgeon>
forum.dlang.org is written in HTML/JS too.
Anything on the web involves HTML, the difference is whether the HTML is the platform (ie HTML5) or just the renderer. And forum.dlang.org uses very little JS (and only optionally). It's certainly not built out of JS.
Apr 29 2014
prev sibling next sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 29 Apr 2014 14:41:17 +0000
James via Digitalmars-d <digitalmars-d puremagic.com> wrote:
just show him vibe.d. it's what node.js wants to be, but failed. ;-)
Apr 29 2014
prev sibling parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Tuesday, 29 April 2014 at 14:41:19 UTC, James wrote:
 I have a friend that is a web developer. I, however want to 
 collaborate with him, so I am trying to get him to learn D. I  
 don't know how to persuade him! How can D be used to greatly 
 assist an HTML5/JavaScript web developer? I decided to go here 
 to get some good answers. How can D be used to interopt with 
 modern web development?
If you want to show him what's possible with D, just show him Cmsed[0] ;) All I'm saying is, if you ever not want to write ajax code again, Cmsed is your friend [1]. [0] https://github.com/rikkimax/Cmsed [1] https://gist.github.com/rikkimax/11043210
Apr 29 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 02:43:43 UTC, Rikki Cattermole 
wrote:
 All I'm saying is, if you ever not want to write ajax code 
 again, Cmsed is your friend [1].
My web.d does some javascript generation too. D: import arsd.web; class Foo : ApiProvider { export int add(int a, int b) { return a+b; } } mixin FancyMain!Foo; Javascript: Foo.add(1, 2).get(alert); // calls alert(3) when it returns The generated JS code creates an object with the same name as the D class with all the export functions as methods that return a proxy object, setting the arguments. You can then modify it and eventually fire off the request with methods like get, getSync, and getHtml which take a function to call with the result. Just one of the many things I miss when doing RoR instead of D :(
Apr 29 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 03:09:43 UTC, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 02:43:43 UTC, Rikki Cattermole 
 wrote:
 All I'm saying is, if you ever not want to write ajax code 
 again, Cmsed is your friend [1].
My web.d does some javascript generation too. D: import arsd.web; class Foo : ApiProvider { export int add(int a, int b) { return a+b; } } mixin FancyMain!Foo; Javascript: Foo.add(1, 2).get(alert); // calls alert(3) when it returns The generated JS code creates an object with the same name as the D class with all the export functions as methods that return a proxy object, setting the arguments. You can then modify it and eventually fire off the request with methods like get, getSync, and getHtml which take a function to call with the result. Just one of the many things I miss when doing RoR instead of D :(
We should probably work together on this sort of stuff! As we seem to have similar ideas
Apr 29 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 03:20:16 UTC, Rikki Cattermole 
wrote:
 We should probably work together on this sort of stuff! As we 
 seem to have similar ideas
Yea, I wrote my version several years ago (IIRC 2009 or early 2010) and since then D has grown as has my knowledge of it. I kinda want to write a web.d 2.0 that cleans everything up but eh I have a lot of things I want to do and web.d 1.0 works so no big rush. The 1.0 has a lot of cool stuff though, like it can avoid JS calls by referencing the result of another function in the URL, all pretty transparently. So like if you wrote, in JS: Foo.add(Foo.add(1,2), 3).get(alert), it should only result in one HTTP request. The proxy object when used as an argument just emits an indirect reference through magic URL params. Kinda cool, though it doesn't go as far as I'd like. Among what I'd like to clean in web.d 2.0: web.d supports what it calls "ApiObjects", which map to RESTful uris: class Poo : ApiObject { this(ApiProvider parent, string identifier) {} auto GET() { } auto POST() {} // etc auto bar() {} } If you went to: /Poo/cool-beans it would call (new Poo(parent, "cool-beans")).GET(). Then /Poo/a/bar calls new Poo("a").bar and so on. The problem is this is really reliant on things like the ending slash, and it issues redirects to force it to be there or not be there. The implementation is also kinda buggy in general, it is supposed to beautifully nest, but it only kinda does. Getting an index of all things also doesn't work quite right, you have to write a separate method for that. So I'd like to clean all that up and actually design it instead of growing on cool hacks as they come to mind. Nested ApiProviders don't work exactly right either. They are supposed to do a chain of magic: class Foo : ApiProvider { auto whatever() {} } class Bar : ApiProvider { alias Foo foo; } Then, /foo/whatever does (new Foo((new Bar))).whatever. That part works. The things is each class can also provide a postProcess method to modify the document after it is generated. That's *supposed* hit everything, but sometimes it doesn't, I think it only works two levels deep right now, really hairy implementation. The other problem is the Javascript generator doesn't really understand nesting. Ideally, nested ApiProviders are made available through dots and nested ApiObjects are workable through JS proxy objects. This looks like what you managed to do so that's cool. I also need to clean up the reflection generation to make it easier to use and make path info accessible outside just the automatic routing (or the low level Cgi.pathInfo which doesn't tell you where it starts!). Reflection should be generated once upon startup then reused forever as an immutable object. Currently, reflection is partially regenerated on each request - eek. I also wrote a _register*Processor family fairly recently (like December 2012) that kinda obviates the old postProcess and back in January this year, changed the session to put it all in cookies instead of files. That stuff is awesome, so much better than the old way. Should consider doing them from the ground up now! (Also, ironically, I was a big pusher for UDAs for web.d... but I barely actually used them after they were made available. I really wanted to put them on parameters tho, otherwise convention over configuration is kinda how i play it LOLOL) oh yeah and it could be documented somewhere other than my brain, the sloppy source, and random forum posts so ppl can know about it all. but meh. All that said, it manages to get the job done for me so I'm not in a huge rush to actually fix any of it.
Apr 29 2014
next sibling parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 04:12:59 UTC, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 03:20:16 UTC, Rikki Cattermole 
 wrote:
 We should probably work together on this sort of stuff! As we 
 seem to have similar ideas
Yea, I wrote my version several years ago (IIRC 2009 or early 2010) and since then D has grown as has my knowledge of it. I kinda want to write a web.d 2.0 that cleans everything up but eh I have a lot of things I want to do and web.d 1.0 works so no big rush. The 1.0 has a lot of cool stuff though, like it can avoid JS calls by referencing the result of another function in the URL, all pretty transparently. So like if you wrote, in JS: Foo.add(Foo.add(1,2), 3).get(alert), it should only result in one HTTP request. The proxy object when used as an argument just emits an indirect reference through magic URL params. Kinda cool, though it doesn't go as far as I'd like. Among what I'd like to clean in web.d 2.0: web.d supports what it calls "ApiObjects", which map to RESTful uris: class Poo : ApiObject { this(ApiProvider parent, string identifier) {} auto GET() { } auto POST() {} // etc auto bar() {} } If you went to: /Poo/cool-beans it would call (new Poo(parent, "cool-beans")).GET(). Then /Poo/a/bar calls new Poo("a").bar and so on. The problem is this is really reliant on things like the ending slash, and it issues redirects to force it to be there or not be there. The implementation is also kinda buggy in general, it is supposed to beautifully nest, but it only kinda does. Getting an index of all things also doesn't work quite right, you have to write a separate method for that. So I'd like to clean all that up and actually design it instead of growing on cool hacks as they come to mind. Nested ApiProviders don't work exactly right either. They are supposed to do a chain of magic: class Foo : ApiProvider { auto whatever() {} } class Bar : ApiProvider { alias Foo foo; } Then, /foo/whatever does (new Foo((new Bar))).whatever. That part works. The things is each class can also provide a postProcess method to modify the document after it is generated. That's *supposed* hit everything, but sometimes it doesn't, I think it only works two levels deep right now, really hairy implementation. The other problem is the Javascript generator doesn't really understand nesting. Ideally, nested ApiProviders are made available through dots and nested ApiObjects are workable through JS proxy objects. This looks like what you managed to do so that's cool. I also need to clean up the reflection generation to make it easier to use and make path info accessible outside just the automatic routing (or the low level Cgi.pathInfo which doesn't tell you where it starts!). Reflection should be generated once upon startup then reused forever as an immutable object. Currently, reflection is partially regenerated on each request - eek. I also wrote a _register*Processor family fairly recently (like December 2012) that kinda obviates the old postProcess and back in January this year, changed the session to put it all in cookies instead of files. That stuff is awesome, so much better than the old way. Should consider doing them from the ground up now! (Also, ironically, I was a big pusher for UDAs for web.d... but I barely actually used them after they were made available. I really wanted to put them on parameters tho, otherwise convention over configuration is kinda how i play it LOLOL) oh yeah and it could be documented somewhere other than my brain, the sloppy source, and random forum posts so ppl can know about it all. but meh. All that said, it manages to get the job done for me so I'm not in a huge rush to actually fix any of it.
It does look like web.d was a bit of a precursor to Cmsed (unintentionally) strangely enough. Although I definitely would like to hear more about asynchronous javascript instead of my synchronous based code and how I can combine it at some point.
Apr 29 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 04:32:33 UTC, Rikki Cattermole 
wrote:
 Although I definitely would like to hear more about 
 asynchronous javascript instead of my synchronous based code 
 and how I can combine it at some point.
The way it works in mine is the proxy object sets a kinda magical helper value in the URL params, telling it to evaluate the named function instead of just trying to convert the data to the right time. So for that one, the regular might be /add?a=1&b=2. With the nested call, we want a={the result of /add?a=1&b=2)&b=3. So it passes it as something like this: "/add?" + urlencode("a=/add?a=1&a=2") + "&b=2&a-type=ServerResult"; So the special "a-type=" tells it that a should not be converted to an integer, but instead parsed and called. The same url parser deconstructs it into a function call and gets the data out (currently, the implementation does it through string intermediaries for ease; it almost literally replaces that with the result in the URL, then re-parses it). This avoids extra calls to the server since it is all done in one set. There's also ways to filter the results that way, for example running a querySelector() call on the server to filter a HTML result for JS. Then, the JS call itself is either synchronous or asynchronous. The sync calls are done with the .getSync method. This generally sucks so I rarely use it, but one cool thing about it is exceptions from the D side are propagated to the Javascript side, making error handling natural. (This is also the way my web.d.php works - it uses PHP's version of opDispatch to make a little class that translate's PHP function calls to http requests for talking to the server. It always uses synchronous calls.... which sucks btw, but it is awfully easy to use: $a = $Foo->add(1, 2).getSync();) The asynch ones just do pretty regular AJAX requests with a callback. The only thing that's interesting is I used the apply function in JS to make it kinda nice: return callback.apply(callbackThis, ourArguments); So things like this kinda works sanely, arguments you pass are forwarded, etc. function someFunction(something, another, result) {} Foo.add(1,2).get(someFunction, "hey", this); // will call someFunction("hey", this, 3); Naturally, there's on error callbacks too that can work the same way. D exceptions are passed as JS objects. (Indeed, in general, all the results from D are passed as objects, it does some JSON.parse action on the JS side and automatic serialization on the D side so many things just work.)
Apr 30 2014
parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 13:48:07 UTC, Adam D. Ruppe wrote:
 On Wednesday, 30 April 2014 at 04:32:33 UTC, Rikki Cattermole 
 wrote:
 Although I definitely would like to hear more about 
 asynchronous javascript instead of my synchronous based code 
 and how I can combine it at some point.
The way it works in mine is the proxy object sets a kinda magical helper value in the URL params, telling it to evaluate the named function instead of just trying to convert the data to the right time. So for that one, the regular might be /add?a=1&b=2. With the nested call, we want a={the result of /add?a=1&b=2)&b=3. So it passes it as something like this: "/add?" + urlencode("a=/add?a=1&a=2") + "&b=2&a-type=ServerResult"; So the special "a-type=" tells it that a should not be converted to an integer, but instead parsed and called. The same url parser deconstructs it into a function call and gets the data out (currently, the implementation does it through string intermediaries for ease; it almost literally replaces that with the result in the URL, then re-parses it). This avoids extra calls to the server since it is all done in one set. There's also ways to filter the results that way, for example running a querySelector() call on the server to filter a HTML result for JS. Then, the JS call itself is either synchronous or asynchronous. The sync calls are done with the .getSync method. This generally sucks so I rarely use it, but one cool thing about it is exceptions from the D side are propagated to the Javascript side, making error handling natural. (This is also the way my web.d.php works - it uses PHP's version of opDispatch to make a little class that translate's PHP function calls to http requests for talking to the server. It always uses synchronous calls.... which sucks btw, but it is awfully easy to use: $a = $Foo->add(1, 2).getSync();) The asynch ones just do pretty regular AJAX requests with a callback. The only thing that's interesting is I used the apply function in JS to make it kinda nice: return callback.apply(callbackThis, ourArguments); So things like this kinda works sanely, arguments you pass are forwarded, etc. function someFunction(something, another, result) {} Foo.add(1,2).get(someFunction, "hey", this); // will call someFunction("hey", this, 3); Naturally, there's on error callbacks too that can work the same way. D exceptions are passed as JS objects. (Indeed, in general, all the results from D are passed as objects, it does some JSON.parse action on the JS side and automatic serialization on the D side so many things just work.)
I see I see. I was assuming there wasn't too much changed on the server side. And mostly in javascript. Netherless quite interesting and advanced usage. Perhaps it could spawn some changes to the router. And hence the ajax route generation.
Apr 30 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 04:12 +0000, Adam D. Ruppe via Digitalmars-d
wrote:
[…]
 Yea, I wrote my version several years ago (IIRC 2009 or early 
 2010) and since then D has grown as has my knowledge of it. I 
 kinda want to write a web.d 2.0 that cleans everything up but eh 
 I have a lot of things I want to do and web.d 1.0 works so no big 
 rush.
I disagree. The lesson from the Bottle/Flask/Tornado experience over the last few years is that it is always better to be working on the next version rather than just stick to maintaining the current version. Yes for using 1.0 on the current jobs, but definitely yes to starting on 2.0 now, especially if there are other to join in and help with the work. Web is not my area per se and I don't have a web-related project I can pin helping out with this effort on, but I would encourage you to work on 2.0. I will have to be looking at Python's asyncio which is Python's "play" in the arena that Twisted used to be king; more vibe.d than web.d. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 29 2014
next sibling parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 04:32:37 UTC, Russel Winder via 
Digitalmars-d wrote:
 On Wed, 2014-04-30 at 04:12 +0000, Adam D. Ruppe via 
 Digitalmars-d
 wrote:
 […]
 Yea, I wrote my version several years ago (IIRC 2009 or early 
 2010) and since then D has grown as has my knowledge of it. I 
 kinda want to write a web.d 2.0 that cleans everything up but 
 eh I have a lot of things I want to do and web.d 1.0 works so 
 no big rush.
I disagree. The lesson from the Bottle/Flask/Tornado experience over the last few years is that it is always better to be working on the next version rather than just stick to maintaining the current version. Yes for using 1.0 on the current jobs, but definitely yes to starting on 2.0 now, especially if there are other to join in and help with the work. Web is not my area per se and I don't have a web-related project I can pin helping out with this effort on, but I would encourage you to work on 2.0. I will have to be looking at Python's asyncio which is Python's "play" in the arena that Twisted used to be king; more vibe.d than web.d.
I've been working on Cmsed/Dvorm/Dakka specifically in the mind of a rather (major) web service. Haven't started it yet, but possibly next semester. I'm of the opinion that we all need to work together to get a damn nice web service framework together. I split up my ORM for this purpose so even if you don't want to use Cmsed you can use it at least. Won't be very nice for normal Vibe users though. I really do want help, Dakka (Actor framework) needs somebody who knows threading/networking communication. I'll eventually get it communicating with other nodes but.. Will opensource if there is interest. Dvorm needs work to make it be usable with relational databases. At worse that means I need OpenDBX dlls for 32/64bit (wasn't as easy to compile as I thought). The hardest part really is how to handle indexes. Cmsed needs documentation by the bucket load. Its also blocked at the moment on dub to make it sensible to do reloading of templates/routes/models. Which will change the way you structure it. Cmsed is already at the point of comparable to other web service frameworks in most other languages.
Apr 29 2014
parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 2014-04-30 at 04:52 +0000, Rikki Cattermole via Digitalmars-d
wrote:
[…]
 I've been working on Cmsed/Dvorm/Dakka specifically in the mind 
 of a rather (major) web service. Haven't started it yet, but 
 possibly next semester.
 I'm of the opinion that we all need to work together to get a 
 damn nice web service framework together.
I would say from anecdotal observation, so no real significance, that most languages end up with a number of frameworks: 1A. Full stack Web framework. 1B. Lightweight HTTP framework. 2A. Full feature networking framework. 2B. Lightweight networking framework. In 1A we have JavaEE, Spring, RoR, Django, Grails, etc. In 2B we have Sinatra, Ratpack, Flask, Bottle, etc. For 2A there is Twisted and 2B asyncio (showing my Python bias here :-)
 I split up my ORM for this purpose so even if you don't want to 
 use Cmsed you can use it at least. Won't be very nice for normal 
 Vibe users though.
Grails is doing this at last (necessitated by supporting NoSQL as well as SQL in the full stack). This is a positive aspect of "componentizing" such large frameworks.
 I really do want help, Dakka (Actor framework) needs somebody who 
 knows threading/networking communication. I'll eventually get it 
 communicating with other nodes but.. Will opensource if there is 
 interest.
I would love to help here, and indeed on a review of std.parallelism, but I have committed my time to a revamp of GPars for Groovy 2.3 and Java 8, so cannot take on another big task in the short term.
 Dvorm needs work to make it be usable with relational databases. 
 At worse that means I need OpenDBX dlls for 32/64bit (wasn't as 
 easy to compile as I thought).
 The hardest part really is how to handle indexes.
Pass I'm afraid, I cannot contribute on this front at all.
 Cmsed needs documentation by the bucket load. Its also blocked at 
 the moment on dub to make it sensible to do reloading of 
 templates/routes/models. Which will change the way you structure 
 it.
Is it viable for Dub to support this? Is someone working on it to create a pull request? Can SCons be an alternative here?
 Cmsed is already at the point of comparable to other web service 
 frameworks in most other languages.
So why would I use it rather than RoR, Grails, Django, Java EE, Spring? Not entirely a rhetorical question. It is good to know early in development why it is worth doing the development rather than using pre-existing tools. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 29 2014
next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 05:25:15 UTC, Russel Winder via 
Digitalmars-d wrote:
 On Wed, 2014-04-30 at 04:52 +0000, Rikki Cattermole via 
 Digitalmars-d
 wrote:
 […]
 I've been working on Cmsed/Dvorm/Dakka specifically in the 
 mind of a rather (major) web service. Haven't started it yet, 
 but possibly next semester.
 I'm of the opinion that we all need to work together to get a 
 damn nice web service framework together.
I would say from anecdotal observation, so no real significance, that most languages end up with a number of frameworks: 1A. Full stack Web framework. 1B. Lightweight HTTP framework. 2A. Full feature networking framework. 2B. Lightweight networking framework. In 1A we have JavaEE, Spring, RoR, Django, Grails, etc. In 2B we have Sinatra, Ratpack, Flask, Bottle, etc. For 2A there is Twisted and 2B asyncio (showing my Python bias here :-)
 I split up my ORM for this purpose so even if you don't want 
 to use Cmsed you can use it at least. Won't be very nice for 
 normal Vibe users though.
Grails is doing this at last (necessitated by supporting NoSQL as well as SQL in the full stack). This is a positive aspect of "componentizing" such large frameworks.
 I really do want help, Dakka (Actor framework) needs somebody 
 who knows threading/networking communication. I'll eventually 
 get it communicating with other nodes but.. Will opensource if 
 there is interest.
I would love to help here, and indeed on a review of std.parallelism, but I have committed my time to a revamp of GPars for Groovy 2.3 and Java 8, so cannot take on another big task in the short term.
 Dvorm needs work to make it be usable with relational 
 databases. At worse that means I need OpenDBX dlls for 
 32/64bit (wasn't as easy to compile as I thought).
 The hardest part really is how to handle indexes.
Pass I'm afraid, I cannot contribute on this front at all.
 Cmsed needs documentation by the bucket load. Its also blocked 
 at the moment on dub to make it sensible to do reloading of 
 templates/routes/models. Which will change the way you 
 structure it.
Is it viable for Dub to support this? Is someone working on it to create a pull request? Can SCons be an alternative here?
I have already posted on the dub forum about this, Sonke Ludwig said he would be working on variables which will at least allow for copying libraries templates ext.
 Cmsed is already at the point of comparable to other web 
 service frameworks in most other languages.
So why would I use it rather than RoR, Grails, Django, Java EE, Spring? Not entirely a rhetorical question. It is good to know early in development why it is worth doing the development rather than using pre-existing tools.
Because Vibe already supports a good amount of functionality I am already a step up (like file uploading and templates). I have a wiki page to what I currently have done vs what I want to do [0]. I really need to do another release of it and Dvorm and give a better indication of what it can do. I posted somewhere else some of the more advanced functionality being ajax generation from routes/models [1]. But I really need some sort of time cost research to reference with regards to how much time it could save (I also need this for a research paper). I basically had to make my own web service framework primarily because from my experience and knowledge of what currently is available, nothing meet my requirements. It would be more work creating it in other languages than to just do it in D from the start. Not to mention I can get pretty good performance out of D in both memory and requests/second. Now if only I could get the ram requirement to compile Cmsed below half a gig I'd be alright (a long shot given my CTFE usage). [0] https://github.com/rikkimax/Cmsed/wiki/Road-map [1] https://gist.github.com/rikkimax/11043210
Apr 29 2014
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 1:24 AM, Russel Winder via Digitalmars-d wrote:
 I would say from anecdotal observation, so no real significance, that
 most languages end up with a number of frameworks:

 1A. Full stack Web framework.
 1B. Lightweight HTTP framework.
 2A. Full feature networking framework.
 2B. Lightweight networking framework.

 In 1A we have JavaEE, Spring, RoR, Django, Grails, etc. In 2B we have
 Sinatra, Ratpack, Flask, Bottle, etc. For 2A there is Twisted and 2B
 asyncio (showing my Python bias here :-)
That does seem to happen. FWIW, IMO the big selling point of D is it's fairly unique knack for letting you eat your cake and still have it. I rather like to think we can manage merging the "full stacks" with the "lightweights".
Apr 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 12:56:03 UTC, Nick Sabalausky 
wrote:
 FWIW, IMO the big selling point of D is it's fairly unique 
 knack for letting you eat your cake and still have it. I rather 
 like to think we can manage merging the "full stacks" with the 
 "lightweights".
Ugh, avoid the full stacks like the plague. They tend to be lockin solutions. Reminds me of Tango in D1 where you risked pulling in all kinds of dependencies. You might dislike this, but I think nimble servers and clean separation with javascript heavy clients are the future. What I don't want: - I have started to avoid server processing of forms, javascript/ajax gives better user experience. - I avoid advanced routing, it adds little and leads to harder to maintain code, give me a regexp based routing table in one location binding request-handlers. - Server side generation should be kept minimal, prevents caching. - Would never consider using serverside javascript generation. What I do want: - Transparent fast distributed in-memory database with logging to a exchangable backing store and with consistency guarantees. - No filesystem dependencies.
Apr 30 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 13:47:11 UTC, Ola Fosheim Grøstad 
wrote:
 You might dislike this, but I think nimble servers and clean 
 separation with javascript heavy clients are the future.

 What I don't want:

 - I have started to avoid server processing of forms, 
 javascript/ajax gives better user experience.
I don't really agree, I do as much work as I can on the server, I like the AJAX stuff to be as stupid simple as setting innerHTML. (Indeed, web.d's automatic javascript has helper functions for this: Server.getSomeData(args).useToReplace(some_element); ) It makes it a lot simpler and gives good compatibility since the client is pretty thin.
 - I avoid advanced routing, it adds little and leads to harder 
 to maintain code, give me a regexp based routing table in one 
 location binding request-handlers.
aye, I think routing is generally ridiculous.
 - Server side generation should be kept minimal, prevents 
 caching.
That's not really true. You can cache individual parts on the server and in some cases, cache the whole page on the client too. Of course, doing things on the server may not need to be cached anyway because you don't have the lag of a million http requests in putting it together.
Apr 30 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 14:57:00 UTC, Adam D. Ruppe wrote:
 - Server side generation should be kept minimal, prevents 
 caching.
That's not really true. You can cache individual parts on the server and in some cases, cache the whole page on the client too.
Mhh… I think there are several different types of files and caching strategies: 1. static files (the ones that never change can be stored at edge caches) 2. pregenerated files (files served from Amazon AWS, Google Cloud Storage, CDNs) 3. proxy cachable files / client cachable files 4. server memcached files 5. fully dynamic files Ola.
Apr 30 2014
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 9:47 AM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Wednesday, 30 April 2014 at 12:56:03 UTC, Nick Sabalausky wrote:
 FWIW, IMO the big selling point of D is it's fairly unique knack for
 letting you eat your cake and still have it. I rather like to think we
 can manage merging the "full stacks" with the "lightweights".
Ugh, avoid the full stacks like the plague. They tend to be lockin solutions. Reminds me of Tango in D1 where you risked pulling in all kinds of dependencies. You might dislike this, but I think nimble servers and clean separation with javascript heavy clients are the future.
That definitely is the direction things are moving right now. Granted, I don't like it, but you're right it's undoubtedly the popular direction and it's unlikely to slow or reverse anytime soon. That said, I don't have an issue with fat clients in general. I usually tend to prefer them (ex: desktop email client). Just not when the "fat client" happens to be inside a web browser, because that tends to not be "fat" client so much as "needlessly bloated" client with an awkward, temperamental UI (example: MS Word and OpenOffice have never lost one keystroke for me from a network hiccup or anything equally trivial).
 What I don't want:

 - I have started to avoid server processing of forms, javascript/ajax
 gives better user experience.
JS can definitely help improve the UX of form validation, no doubt about that, but it's important to remember that server-side validation is still necessary anyway, regardless of what you do on the client.
 - I avoid advanced routing, it adds little and leads to harder to
 maintain code, give me a regexp based routing table in one location
 binding request-handlers.
Same here. I don't like having my available HTTP interfaces scattered across my codebade, and I definitely don't like having them implicit based on member-function visibility (I've used such frameworks before. Not personally my cup of tea). What I *do* love is having a canonical table defining my entire HTTP interface in one easy location. The extra typing or non-DRYness of that is a mere triviality in my experience (and I'm normally a huge DRY buff).
 - Server side generation should be kept minimal, prevents caching.
Ehh, yes and no. Server side generation is usually fine, just not when it's done more often than necessary. And traditional server-side web technologies definitely tend to do it more than necessary, For example, consider a page containing a blog post with (non-Disqus) user comments: It's a complete waste for the server to regenerate such a page upon every request, PHP/ASP-style. That's because it doesn't *change* upon every viewing - it only changes on every post and edit (and not even every one of those, if there's enough comments to trigger paging). So unless the page's rate of comment "submissions/edits" approaches the rate of comment "views" (unlikely...except maybe on YouTube ;) ), then it's best to re-generate upon posts/edits and then cache that. So you still get caching benefits, but with no need to make *all* the clients duplicate the exact same page-generating effort as each other upon every viewing. Supporting login stuff (ex: "Hello, [your name here]! Logout?") doesn't really mess this up either. The vast majority of the page can still be cached by the server. Then, "generating" it for each user doesn't need to be anything more resource-intensive than this: void loginUser(string name) { session.user.loggedIn = true; session.user.name = name; // Whatever template engine you want: session.user.loggedInUI = `Hello <b>`~name~`</b>! <a href="/logout">Logout</a>`; } enum commonLoggedOutUI = `Login: <form>Username:<input...> Pass:<input...></form>`; void showMyPage(OutRange response, User user) { // myPage was automatically split into parts A and B // last time it was updated: response.put(myPagePartA); if(session.user.loggedIn) response.put(session.user.loggedInUI); else response.put(commonLoggedOutUI); response.put(myPagePartB); }
 - Would never consider using serverside javascript generation.
Heh, I've actually done that on old-style ASP (ages ago). It was both confusing and interesting.
 What I do want:

 - Transparent fast distributed in-memory database with logging to a
 exchangable backing store and with consistency guarantees.

 - No filesystem dependencies.
I'll take those, plus a large vanilla latte, please. :) "Thank you, come again!"
Apr 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 15:27:48 UTC, Nick Sabalausky 
wrote:
 That definitely is the direction things are moving right now. 
 Granted, I don't like it, but you're right it's undoubtedly the 
 popular direction and it's unlikely to slow or reverse anytime 
 soon.
I'm not sure if I like it either, but I think websites are getting more usable now. For a while it was a shitty stuttering mess of HTML and JS that made me longing for an AntiWeb browser with community maintained per-site AI that turns the horrible HTML-mess into semantic markup that you can style yourself. I actually have a file called antiweb.d here… ;) I also had high hopes for XSLT. I remember requiring studentprojects to serve XML from the server, and transform it to HTML using XSLT in the browser back in 2002 or so. And XSLT support was actually quite good, at least until the mobile shit hit the fan. Unfortunately connections were still slow so XSLT based rendering had to wait until the whole XML was downloaded. Today I think it might work out quite nicely, but I doubt anyone even remembers that browser can do XSLT today. Actually, I am not even sure if they all still support it? The weird thing is that SEO and search engine priorities are the ones that keep the dynamic websites from going fully dynamic by their anti-dynamic measures (punishing non-static content) and they are also the ones that are pushing semantic markup such as itemscope/itemprop microdata. On the other side of the fence the Wordpress authors are having a lot of power. Whatever Wordpress makes easy will dominate a large portion of the web. I think that is so sad, because the Wordpress codebase is… err… junk. I am not even going to use the term «a pile of junk» which would suggest that there is some sense of structure to it. I think it is more like a scattered mutating spaghetti dinner gone terribly wrong, slowly emerging from every toilet in every household taking over the earth… like the classic horror movies from the 1950s.
 JS can definitely help improve the UX of form validation, no 
 doubt about that, but it's important to remember that 
 server-side validation is still necessary anyway, regardless of 
 what you do on the client.
Yup. So a must have is a good infrastructure for specifying database invariants and transactions. Ideally it should execute like a stored procedure thus leaving the server logic pretty clean.
 What I *do* love is having a canonical table defining my entire 
 HTTP interface in one easy location. The extra typing or 
 non-DRYness of that is a mere triviality in my experience (and 
 I'm normally a huge DRY buff).
Yep, it also acts like always-up-to-date documentation when you come back to the source code 6 months later trying to figure out the main structure.
 So unless the page's rate of comment "submissions/edits" 
 approaches the rate of comment "views" (unlikely...except maybe 
 on YouTube ;) ), then it's best to re-generate upon posts/edits 
 and then cache that. So you still get caching benefits, but 
 with no need to make *all* the clients duplicate the exact same 
 page-generating effort as each other upon every viewing.
Well, I would probably use JS… ;-) But I am pragmatic. Caching and pregeneration can lead to bugs and complications. So it is usually a good idea to just do a dynamic version first and then add caching when needed. I also sometimes use a dynamic template during development, and then just save a static version for release if I know that it won't change.
 I'll take those, plus a large vanilla latte, please. :) "Thank 
 you, come again!"
You're welcome! I think it is realistic now for smaller sites (say 1-8 servers) where you have enough RAM to hold perhaps 10 times the information the site will ever provide. One should be able to sync 8 servers that have relative few write operations easily. So, reading the log might take some time during startup, but with an efficient format… it probably could complete quickly for 1GB of data.
Apr 30 2014
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 4/30/2014 12:32 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On the other side of the fence the Wordpress authors are having a lot of
 power. Whatever Wordpress makes easy will dominate a large portion of
 the web. I think that is so sad, because the Wordpress codebase is… err…
 junk.
I've used Wordpress. Its codebase isn't the only thing bad about it ;)
 I am not even going to use the term «a pile of junk» which would
 suggest that there is some sense of structure to it. I think it is more
 like a scattered mutating spaghetti dinner gone terribly wrong, slowly
 emerging from every toilet in every household taking over the earth…
 like the classic horror movies from the 1950s.
Sounds pretty much exactly what I'd expect from just about any PHP-based application. :/
 JS can definitely help improve the UX of form validation, no doubt
 about that, but it's important to remember that server-side validation
 is still necessary anyway, regardless of what you do on the client.
Yup. So a must have is a good infrastructure for specifying database invariants and transactions. Ideally it should execute like a stored procedure thus leaving the server logic pretty clean.
I have to admit I've been in the habit of avoiding anything beyond basic SELECT/INSERT/UPDATE/DELETE and CREATE TABLE. Not that I haven't used them, but I really should have more familiarity with the other stuff than I do. Ugh, but SQL can be such a pain, especially with all the vendor differences, and when compared to accomplishing something in whatever language I'm invoking SQL from.
Apr 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 16:56:11 UTC, Nick Sabalausky 
wrote:
 Sounds pretty much exactly what I'd expect from just about any 
 PHP-based application. :/
Modern PHP isn't so bad. I can write acceptable code in PHP. Though, I only do so when there is no other option, since it is the least desirable option next to Perl. The good thing about PHP is that default installs tend to have good C libraries. I think it would have died without that. So, if PHP is ok then it must be the PHP programmers that are to blame. I shudder to think what happens with a niche community if they pick it as the next fad… It could destroy any upcoming programming community with spaghetti-hell. Are you sure you want to market D as a web platform?
 familiarity with the other stuff than I do. Ugh, but SQL can be 
 such a pain, especially with all the vendor differences, and 
 when compared to accomplishing something in whatever language 
 I'm invoking SQL from.
You can implement it in the ORB or wherever unit that provides transactions. I was more pointing to what I find useful conceptually in terms of layers: 1. user input on the client 2. validate on client 3. post using ajax 4. server unwraps the data and blindly inserts it into the database 5. if transaction fails, notify client, goto 1 6. done. Another good reason for fat clients is that the edit/run cycle is tighter and it is easier to run a debugger on it. It makes sense to put most of the code where you can mutate it easily.
Apr 30 2014
next sibling parent reply Byron <byron.heads gmail.com> writes:
On Wed, 30 Apr 2014 17:17:01 +0000, Ola Fosheim Grøstad wrote:

 4. server unwraps the data and blindly inserts it into the database 
ummmm...... wtf? This is why hackers keep stealing my credit card.... Client side validation should only be used for giving users immediate fed back and saving cycles. You do know I can look at your js, find all of your ajax calls and send what ever data I want right..
Apr 30 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 30 April 2014 at 17:23:39 UTC, Byron wrote:
 Client side validation should only be used for giving users 
 immediate fed
 back and saving cycles. You do know I can look at your js, find 
 all of
 your ajax calls and send what ever data I want right..
If the security model depends on code being hidden then there is something very wrong with it. The database should do all the veracity checks and apply all the consistency constraints. The server should merely prepare the data. If any constraints triggers the transaction is rolled back. This becomes even more important when you have multiple servers and versions of the server software maintained by various divisions writing to the same database.
Apr 30 2014
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 30 April 2014 at 17:17:02 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 30 April 2014 at 16:56:11 UTC, Nick Sabalausky 
 wrote:
 Sounds pretty much exactly what I'd expect from just about any 
 PHP-based application. :/
Modern PHP isn't so bad. I can write acceptable code in PHP. Though, I only do so when there is no other option, since it is the least desirable option next to Perl. The good thing about PHP is that default installs tend to have good C libraries. I think it would have died without that. So, if PHP is ok then it must be the PHP programmers that are to blame. I shudder to think what happens with a niche community if they pick it as the next fad… It could destroy any upcoming programming community with spaghetti-hell. Are you sure you want to market D as a web platform?
This hasn't happened to Ruby (or Rails for that matter), which is definitely marketed as a web platform. Most of the Ruby code that I've seen is of exceptionally high quality. That's true not only regarding the code itself, but also for the interfaces it provides (in the case of libraries), which are usually well thought out. For PHP, on the other hand... I believe this has a lot to do with the language. Apparently it's harder to write bad code in some languages than in others.
 familiarity with the other stuff than I do. Ugh, but SQL can 
 be such a pain, especially with all the vendor differences, 
 and when compared to accomplishing something in whatever 
 language I'm invoking SQL from.
You can implement it in the ORB or wherever unit that provides transactions. I was more pointing to what I find useful conceptually in terms of layers: 1. user input on the client 2. validate on client 3. post using ajax 4. server unwraps the data and blindly inserts it into the database 5. if transaction fails, notify client, goto 1 6. done.
IMO the client shouldn't do any validation, unless you can really, really trust it. That's why I like to do things the following way: 1. user input on the client 2. post using ajax 3. server validates and stores the data 4a. if transaction or data is invalid fails, send errors to the client 4b. if everything's ok, tell the client to redirect to the next page 5. on the client, add error CSS classes to the relevant fields, or execute the redirect I've created a gem that does almost all of that transparently. I just need to mark the form with "remote: true", and adhere to a few simple naming conventions (which Rails' form generators do automatically).
May 01 2014
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
On Thursday, 1 May 2014 at 13:33:50 UTC, Marc Schütz wrote:
 IMO the client shouldn't do any validation, unless you can 
 really, really trust it. That's why I like to do things the 
 following way:

 1. user input on the client
 2. post using ajax
 3. server validates and stores the data
 4a. if transaction or data is invalid fails, send errors to the 
 client
 4b. if everything's ok, tell the client to redirect to the next 
 page
 5. on the client, add error CSS classes to the relevant fields, 
 or execute the redirect
That's a lot of unnecessary back and forth to the server for a JS-based design. Plus it avoids some of the nicer UX enhancements JS can enable, like validate-as-you-type, and does so without the benefit of not requiring JS. Kind of a worst of both worlds (no offence). Naturally, the server needs to do validation no matter what. But there's nothing wrong with doing an optional preliminary validation on the client side first.
May 01 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 1 May 2014 at 15:11:07 UTC, Nick Sabalausky wrote:
 On Thursday, 1 May 2014 at 13:33:50 UTC, Marc Schütz wrote:
 IMO the client shouldn't do any validation, unless you can 
 really, really trust it. That's why I like to do things the 
 following way:

 1. user input on the client
 2. post using ajax
 3. server validates and stores the data
 4a. if transaction or data is invalid fails, send errors to 
 the client
 4b. if everything's ok, tell the client to redirect to the 
 next page
 5. on the client, add error CSS classes to the relevant 
 fields, or execute the redirect
That's a lot of unnecessary back and forth to the server for a JS-based design. Plus it avoids some of the nicer UX enhancements JS can enable, like validate-as-you-type, and does so without the benefit of not requiring JS. Kind of a worst of both worlds (no offence).
Well, naturally I disagree :-) It's exactly two requests to the server, same as for a normal form submission without JS: - one for the actual submission => server responds either with the errors, or with a redirect URL - and another one for requesting the next page (only if everything was ok) Technically, you could already send the contents of the new page with the server response, but this has several drawbacks (doesn't change the URL, double POST on reload, etc.), so a redirect is pretty much standard. I don't see how you could improve on that in respect to the number of requests... It also degrades gracefully if JS is not enabled: In this case, the form submission will not be intercepted by the JS and therefore won't be turned into an AJAX request. The server notices that it's not an XHR request, and automatically responds by rerendering the form view with all the CSS classes and error messages in place. (This requires a bit more work on the server side, but not a lot.)
 Naturally, the server needs to do validation no matter what. But
 there's nothing wrong with doing an optional preliminary
 validation on the client side first.
Exactly. I just feel that client-side validation is unnecessary duplication in most cases. But sure, it can be used where it makes sense.
May 01 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-05-01 19:56, "Marc Schütz" <schuetzm gmx.net>" wrote:

 Exactly. I just feel that client-side validation is unnecessary
 duplication in most cases. But sure, it can be used where it makes sense.
There's a gem [1] for that. Although it seems that one is not maintained anymore. [1] https://github.com/DockYard/client_side_validations-simple_form -- /Jacob Carlborg
May 01 2014
prev sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Thursday, 1 May 2014 at 13:33:50 UTC, Marc Schütz wrote:
 IMO the client shouldn't do any validation, unless you can 
 really, really trust it.
Client side validation is about better feedback. Today's browsers are fast enough for doing field validation for every keystroke.
 4a. if transaction or data is invalid fails, send errors to the 
 client
Without client side validation you need more detailed errors from the server.
May 01 2014
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 30 April 2014 at 04:32:37 UTC, Russel Winder via 
Digitalmars-d wrote:
 The lesson from the Bottle/Flask/Tornado experience over the 
 last few years is that it is always better
 to be working on the next version rather than just
 stick to maintaining the current version.
Maybe, but in general, I write what I use, and right now I don't have any significant new D web projects in the pipeline. I still have a couple old ones going, but the new boss said no in switching to D from Ruby (the rest of the team doesn't know it), so the question now is: do I want to spend my nights writing something I won't be using right now or doing something else? for now, the answer is doing something else. That might change eventually tho.
 in the arena that Twisted used to be king; more vibe.d than 
 web.d.
I think the vibe.d folks are doing pretty cool work too. Actually, my web.d could arguably be used with vibe.d; a vibe backend for my cgi.d is a realistic possibility, and then web.d is a pretty straight-forward add-on on top of that. In fact, it might not even be very hard, I just haven't tried yet. (And the other libs are already independent, I think Nick uses my dom.d with vibe already.) Though, my little httpd isn't awful so again, "works for me" is a lot of inertia to overcome.
Apr 30 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 02:43:43 UTC, Rikki Cattermole 
wrote:
 On Tuesday, 29 April 2014 at 14:41:19 UTC, James wrote:
 I have a friend that is a web developer. I, however want to 
 collaborate with him, so I am trying to get him to learn D. I  
 don't know how to persuade him! How can D be used to greatly 
 assist an HTML5/JavaScript web developer? I decided to go here 
 to get some good answers. How can D be used to interopt with 
 modern web development?
If you want to show him what's possible with D, just show him Cmsed[0] ;) All I'm saying is, if you ever not want to write ajax code again, Cmsed is your friend [1]. [0] https://github.com/rikkimax/Cmsed [1] https://gist.github.com/rikkimax/11043210
Having a quick look at Cmsed I must admit I like plain vibe.d much more despite the added features :( Forced module coupling and OO-heavy design is big loss compared to design simplicity and independence of base vibe.d modules. For example I can't imagine a single case when I'd prefer class-based route definition to stock delegate-based.
Apr 29 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 04:10:14 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 02:43:43 UTC, Rikki Cattermole 
 wrote:
 On Tuesday, 29 April 2014 at 14:41:19 UTC, James wrote:
 I have a friend that is a web developer. I, however want to 
 collaborate with him, so I am trying to get him to learn D. I
  don't know how to persuade him! How can D be used to greatly 
 assist an HTML5/JavaScript web developer? I decided to go 
 here to get some good answers. How can D be used to interopt 
 with modern web development?
If you want to show him what's possible with D, just show him Cmsed[0] ;) All I'm saying is, if you ever not want to write ajax code again, Cmsed is your friend [1]. [0] https://github.com/rikkimax/Cmsed [1] https://gist.github.com/rikkimax/11043210
Having a quick look at Cmsed I must admit I like plain vibe.d much more despite the added features :( Forced module coupling and OO-heavy design is big loss compared to design simplicity and independence of base vibe.d modules. For example I can't imagine a single case when I'd prefer class-based route definition to stock delegate-based.
The classes are unfortunately just a container for routes. So if you got a better way, that can provide the same functionality, I'd love for a plan on how to do it! Basically my idea is that you register as little as possible. That was why I went with a class for routes. I'm really gunning for less, simpler = more. And for medium-large sites thats kinda important.
Apr 29 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 04:21:20 UTC, Rikki Cattermole 
wrote:
 Having a quick look at Cmsed I must admit I like plain vibe.d 
 much more despite the added features :( Forced module coupling 
 and OO-heavy design is big loss compared to design simplicity 
 and independence of base vibe.d modules.

 For example I can't imagine a single case when I'd prefer 
 class-based route definition to stock delegate-based.
The classes are unfortunately just a container for routes. So if you got a better way, that can provide the same functionality, I'd love for a plan on how to do it! Basically my idea is that you register as little as possible. That was why I went with a class for routes. I'm really gunning for less, simpler = more. And for medium-large sites thats kinda important.
Why can't stand-alone annotated function be a valid route? Route is pretty much method + url + handler and first two can be inferred by convention in many cases (as done in vibe.web.rest & Co). Right now your approach actually results in more code than stock vibe.d (stand-alone function + explicit route registration).
Apr 30 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 09:41:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 04:21:20 UTC, Rikki Cattermole 
 wrote:
 Having a quick look at Cmsed I must admit I like plain vibe.d 
 much more despite the added features :( Forced module 
 coupling and OO-heavy design is big loss compared to design 
 simplicity and independence of base vibe.d modules.

 For example I can't imagine a single case when I'd prefer 
 class-based route definition to stock delegate-based.
The classes are unfortunately just a container for routes. So if you got a better way, that can provide the same functionality, I'd love for a plan on how to do it! Basically my idea is that you register as little as possible. That was why I went with a class for routes. I'm really gunning for less, simpler = more. And for medium-large sites thats kinda important.
Why can't stand-alone annotated function be a valid route? Route is pretty much method + url + handler and first two can be inferred by convention in many cases (as done in vibe.web.rest & Co).
The only way I know of that doesn't result in a container is registerRoutes!"mymodule"; Instead of registerRoute!MyRoute; Now if I could get access to a list of all the modules and hence all routes at CTFE then that wouldn't be an issue. Same deal for models. Basically give me a way that doesn't impose upon the user to manually register a route and the symbol is available at CTFE, then I'll use it. I just don't know it. There is some benefits of having a container for routes however. Being able to add UDAs to that group of routes. I.e. Don't generate javascript, give them a name/grouping. While its possible without it, its a bit more distinct.
Apr 30 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 10:01:51 UTC, Rikki Cattermole 
wrote:
 Why can't stand-alone annotated function be a valid route? 
 Route is pretty much method + url + handler and first two can 
 be inferred by convention in many cases (as done in 
 vibe.web.rest & Co).
The only way I know of that doesn't result in a container is registerRoutes!"mymodule"; Instead of registerRoute!MyRoute;
Well you need to specify this only once with root module (usually app.d) supplied as a parameter. You can query all imported modules recursively from it.
 Now if I could get access to a list of all the modules and 
 hence all routes at CTFE then that wouldn't be an issue. Same 
 deal for models.
This can't be done with same guarantees as runtime reflection because of separate compilation. Requirement to transitively to import everything from root module is necessary. I don't see it much of a burden though.
 There is some benefits of having a container for routes however.
 Being able to add UDAs to that group of routes. I.e. Don't 
 generate javascript, give them a name/grouping.
 While its possible without it, its a bit more distinct.
There are definitely several benefits of having aggregated compile-time known list of routes. Actually I have added it as one of examples for my DConf talk just yesterday :) This list, however, can possibly be built automatically via reflection provided single root entry point. I think good flexible framework should provide user both options and infer as much as possible by convention.
Apr 30 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added it as 
 one of examples for my DConf talk just yesterday :) This list, 
 however, can possibly be built automatically via reflection 
 provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Apr 30 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki Cattermole 
wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added it as 
 one of examples for my DConf talk just yesterday :) This list, 
 however, can possibly be built automatically via reflection 
 provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Apr 30 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 12:55:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added it 
 as one of examples for my DConf talk just yesterday :) This 
 list, however, can possibly be built automatically via 
 reflection provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Perhaps but in the compiler, the file system wouldn't actually be changed. And the explicit package.d files would merely be overrides.
Apr 30 2014
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 30 April 2014 at 13:03:43 UTC, Rikki Cattermole 
wrote:
 On Wednesday, 30 April 2014 at 12:55:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added it 
 as one of examples for my DConf talk just yesterday :) This 
 list, however, can possibly be built automatically via 
 reflection provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Perhaps but in the compiler, the file system wouldn't actually be changed. And the explicit package.d files would merely be overrides.
There's nothing stopping you from automatically making a temporary directory structure for building. No need to alter it in-place.
Apr 30 2014
parent reply "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 13:28:28 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 13:03:43 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:55:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added it 
 as one of examples for my DConf talk just yesterday :) This 
 list, however, can possibly be built automatically via 
 reflection provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Perhaps but in the compiler, the file system wouldn't actually be changed. And the explicit package.d files would merely be overrides.
There's nothing stopping you from automatically making a temporary directory structure for building. No need to alter it in-place.
The way this discussion is going I'll have a new build manager built specifically for web development. This is where I'm gonna say 'no'. Hmm now if only I understand assembly better. And was able to write a JIT then maybe. Maybe then I could implement my evil ideas.
Apr 30 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 30 April 2014 at 13:37:33 UTC, Rikki Cattermole 
wrote:
 On Wednesday, 30 April 2014 at 13:28:28 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 13:03:43 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:55:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki 
 Cattermole wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having aggregated 
 compile-time known list of routes. Actually I have added 
 it as one of examples for my DConf talk just yesterday :) 
 This list, however, can possibly be built automatically 
 via reflection provided single root entry point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Perhaps but in the compiler, the file system wouldn't actually be changed. And the explicit package.d files would merely be overrides.
There's nothing stopping you from automatically making a temporary directory structure for building. No need to alter it in-place.
The way this discussion is going I'll have a new build manager built specifically for web development. This is where I'm gonna say 'no'. Hmm now if only I understand assembly better. And was able to write a JIT then maybe. Maybe then I could implement my evil ideas.
A JIT for D? That would be many, many man-years of work.
Apr 30 2014
next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 13:50:18 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 13:37:33 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 13:28:28 UTC, John Colvin wrote:
 On Wednesday, 30 April 2014 at 13:03:43 UTC, Rikki Cattermole 
 wrote:
 On Wednesday, 30 April 2014 at 12:55:36 UTC, Dicebot wrote:
 On Wednesday, 30 April 2014 at 12:52:36 UTC, Rikki 
 Cattermole wrote:
 On Wednesday, 30 April 2014 at 12:38:32 UTC, Dicebot wrote:
 There are definitely several benefits of having 
 aggregated compile-time known list of routes. Actually I 
 have added it as one of examples for my DConf talk just 
 yesterday :) This list, however, can possibly be built 
 automatically via reflection provided single root entry 
 point.

 I think good flexible framework should provide user both 
 options and infer as much as possible by convention.
Hmm interesting idea, although I'd feel a lot happier about it if the compiler was able to (with a switch most likely) infer/create automatically package.d files with auto import of all sub modules if it doesn't exist.
Sounds like typical use case for imaginary dub plugin system.
Perhaps but in the compiler, the file system wouldn't actually be changed. And the explicit package.d files would merely be overrides.
There's nothing stopping you from automatically making a temporary directory structure for building. No need to alter it in-place.
The way this discussion is going I'll have a new build manager built specifically for web development. This is where I'm gonna say 'no'. Hmm now if only I understand assembly better. And was able to write a JIT then maybe. Maybe then I could implement my evil ideas.
A JIT for D? That would be many, many man-years of work.
Nah written in D. But in saying that, it would probably be one of the first languages I'd have a go at.
Apr 30 2014
prev sibling parent Etienne <etcimon gmail.com> writes:
 A JIT for D? That would be many, many man-years of work.
Wrong! It would be quite easy. I've figured it out myself. I've thought of using Pegged with PEG/BNF ParseTrees, made faster using ParseTree serialization matched to the source's CRC32-encoding for memoization, with a multi-threaded model of tree-generation when branching in Or! steps. Then, the interpretation stage can re-create the D environment with hash maps of a "Entity" Variant of D types, functions, values and instantiations added with their respective identifiers, each as a single Entity struct containing their instructions as a simple array. e.g. struct Entity { Entity[] scope; Entity[] instructions } Once that's done, you should have all your types and objects in HashMaps, ready to execute with an entry point. You move through the instructions with a foreach loop by looking up function calls and expecting the appropriate return type. Call me crazy, but I think typed variants would be easier and faster to handle than the regular casting methods that interpreted languages use currently. Anyway, the hardest part again would be to write a good garbage collector.
Apr 30 2014
prev sibling parent reply "logicchains" <jonathan.t.barnard gmail.com> writes:
On Wednesday, 30 April 2014 at 13:37:33 UTC, Rikki Cattermole 
wrote:
 Hmm now if only I understand assembly better. And was able to 
 write a JIT then maybe. Maybe then I could implement my evil 
 ideas.
You don't necessarily need to understand assembly to write a JIT. You could instead have your bytecode take the form of D functions (such as int16 addI16(int16 a, int16 b), for instance) so you're essentially generating an array of D functions then iterating over them evaluating them. This would obviously be slower than generating assembly directly, but would still be faster than an interpreter, and you could still do some optimisation on it.
Apr 30 2014
parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 30 April 2014 at 14:11:20 UTC, logicchains wrote:
 On Wednesday, 30 April 2014 at 13:37:33 UTC, Rikki Cattermole 
 wrote:
 Hmm now if only I understand assembly better. And was able to 
 write a JIT then maybe. Maybe then I could implement my evil 
 ideas.
You don't necessarily need to understand assembly to write a JIT. You could instead have your bytecode take the form of D functions (such as int16 addI16(int16 a, int16 b), for instance) so you're essentially generating an array of D functions then iterating over them evaluating them. This would obviously be slower than generating assembly directly, but would still be faster than an interpreter, and you could still do some optimisation on it.
Been there. Drunmeta [0]. Theres a reason why I'm not going down that road anymore ;) [0] https://github.com/rikkimax/drunmeta
Apr 30 2014