Open StefanScott opened 9 years ago
Stefan, thank you for your positive review. It takes some time for me to prepare answers, I'll do it in a couple of days.
For now I answer to your very last question: in fact, I didn't write applications requiring complex interaction with users yet. Projects like etab or ecosrv (unfortunately, I will not maintain it any longer because I have changed the job) all use DB in a straightforward way. So your survey may be the first one in this area :)
Sergey -
Thank you again for providing these examples.
I understand that econat (and possibly etab) may be more a read-only db, with less user interaction (editing records).
I am interested in basic CRUD where there would be more editing by the users - so I am eager to get some kind of autocomplete widget to let the user easily select the foreign-key fields.
I understand you are busy so there is no need to respond quickly. I will also be busy doing other work, and there is plenty of excellent existing code you have written which I can continue studying.
On Mon, Jul 13, 2015 at 5:00 PM, Sergey Mironov notifications@github.com wrote:
Stefan, thank you for your positive review. It takes some time for me to prepare the answers, I'll do it in a couple of days.
For now I answer to your very last question: in fact, I didn't write applications requiring complex interaction with users yet. Projects like etab or ecosrv (unfortunately, I will not maintain it any longer because I have changed the job) all use DB in a straightforward way. So your survey may be the first one in this area :)
— Reply to this email directly or view it on GitHub https://github.com/grwlf/urweb-etab/issues/1#issuecomment-121038141.
Hi, Stefan, here is the longer answer from me:
SUMMARY:
Because you are actively programming in Ur/Web on practical projects, reading your code is very helpful for beginners like me to learn typical idioms and good style.
Perhaps you may someday also find some time to publish some annotations or commentaries to some of your code.
Although much of it may seem "obvious" to you - any commentaries regarding your code may be quite novel and instructive to beginner Ur/Web programmers such as myself.
I am really a beginner with Ur/Web - but I have studied functional languages such as ML and Haskell a lot.
The language I use mostly has been Maude - which is similar to ML and Haskell (differences: Maude has subtypes; it is first-level, not higher-level; and Maude's modules can contain axioms, unlike ML modules).
Thank you for sharing these contributions. I will continue to study them.
Well, I've been asking for nice idioms and your
Etab.ur
certainly has many nice idioms.I am reading it more closely now and learning a lot :-)
https://github.com/grwlf/urweb-etab/blob/master/Etab.ur
I had of course repeatedly skimmed the
grwlf/etab
repository (apparently modeling archery competitions) 3-4 times in the past few months, expecting that (along with your other worksecosat
andoil-price
) I might be seeing some good examples there to learn from.I had also looked a few times at your
uru3
andurweb-soup
andurweb-prelude
.I did not yet use them because I was afraid of possible additional complications due to the cake file - but perhaps I should learn to adapt to this as a necessity for building larger Ur/Web applications, as you have.
I have some initial basic questions:
(1) Your code uses a cake file, based on Haskell.
So I should first also install Haskell, in order to use Etab, correct?
Actually, no. You don't have to have Haskell to use Etab. cake3 is a Haskell
tool which 'executes' Cake*hs files. The result of execution is Makefile,
Makefile.dev and the whole folder of autogenerated modules. I keep those files
in the repository so you can just make
everything.
You need Haskell only if you want to join the development of urweb-etab. That is because cake3 is used to build the Ur/Web FFI wrappers and to embed binary files into the application.
By the way, did you notice that there are no lib.urp files in library folders?
That is because lib.urp is a generated file too. The reason is that we don't
alway know the linker flags since they may depend on end-user system (it is
pkg-config's job to find them). So if we speak about library project like
urweb-soup, than you shoud execute make lib
in order to build lib.urp. After
that, you may use the library as usual (I repeat, no Haskell is needed for
building).
(from time to time I forget to add something important for building the repo, it should be considered as a bug))
(2) The purpose of this function:
https://github.com/grwlf/urweb-soup/blob/dcd4131a5cf2b51154c4c432fd8c263c1175f4fa/Unsafe.urs
Is to allow the programmer to include arbitrary HTML fragments in the HTML output from the Ur/Web compiler, correct?
These
s2xhead
ands2xbody
functions were contributed by you then?
Yes, it was me who wrote them. I use them to embed third-party snippets like google Analytics code. Such snippets usually has to be inserted as-is, re-writing their logic in Ur/Web is IMHO a bad way.
I was expecting that
s2xhead
ands2xbody
would specify the concrete location to "splice in" the resulting HTML fragments - but now I see that it these functions merely do some kind of "wrapping".Now I see that the specification of the location where to "splice in" the fragment of course simply occurs at the particular location of insertion of value 'donate' (which calls
Unsafe.s2xbody
), towards the end, here:</ul> {donate} </p> </xml>
I think that Ur/Web type system can't be used to hardly restrict the location of a snippet. It allows us to say something like "don't insert this thing into
SUMMARY:
Because you are actively programming in Ur/Web on practical projects, reading your code is very helpful for beginners like me to learn typical idioms and good style.
Perhaps you may someday also find some time to publish some annotations or commentaries to some of your code.
Although much of it may seem "obvious" to you - any commentaries regarding your code may be quite novel and instructive to beginner Ur/Web programmers such as myself.
I am really a beginner with Ur/Web - but I have studied functional languages such as ML and Haskell a lot.
The language I use mostly has been Maude - which is similar to ML and Haskell (differences: Maude has subtypes; it is first-level, not higher-level; and Maude's modules can contain axioms, unlike ML modules).
Thank you for sharing these contributions. I will continue to study them.
Well, I've been asking for nice idioms and your
Etab.ur
certainly has many nice idioms.I am reading it more closely now and learning a lot :-)
https://github.com/grwlf/urweb-etab/blob/master/Etab.ur
I had of course repeatedly skimmed the
grwlf/etab
repository (apparently modeling archery competitions) 3-4 times in the past few months, expecting that (along with your other worksecosat
andoil-price
) I might be seeing some good examples there to learn from.I had also looked a few times at your
uru3
andurweb-soup
andurweb-prelude
.I did not yet use them because I was afraid of possible additional complications due to the cake file - but perhaps I should learn to adapt to this as a necessity for building larger Ur/Web applications, as you have.
I have some initial basic questions:
(1) Your code uses a cake file, based on Haskell.
So I should first also install Haskell, in order to use Etab, correct?
(2) The purpose of this function:
https://github.com/grwlf/urweb-soup/blob/dcd4131a5cf2b51154c4c432fd8c263c1175f4fa/Unsafe.urs
Is to allow the programmer to include arbitrary HTML fragments in the HTML output from the Ur/Web compiler, correct?
These
s2xhead
ands2xbody
functions were contributed by you then?I was expecting that
s2xhead
ands2xbody
would specify the concrete location to "splice in" the resulting HTML fragments - but now I see that it these functions merely do some kind of "wrapping".Now I see that the specification of the location where to "splice in" the fragment of course simply occurs at the particular location of insertion of value 'donate' (which calls
Unsafe.s2xbody
), towards the end, here:Some other interesting idioms I am noticing:
Idiom 1: Blessing a directory.
I didn't know you could just do this, and assign the result to a value.
But of course this makes sense now: bless isn't some exceptional syntax, it is merely a function call, and returns a useful value.
Idiom 2: It is interesting that you aren't even use an SQL database at all. Just using native ML-style data types.
This is fascinating and encouraging to me.
UPDATE: Ah I see later you do use an SQL database - and you have interesting DML code to interface between the ML-style datatypes, and the SQL.
Idiom 3:
As mentioned above, I had looked at the uru3 repository a few times in the past months. I guess I got intimidated by the cake file, and wanted to avoid using any extra layers in my initial, minimal (ie, "Hello World") attempts to implement some sort of autocomplete widget in Ur/Web.
Now I also recall that any cake file is simply necessary 'glue' code to put files together at the OS level, and I see that the cake dialect being used is Haskell (not C), so I understand that I should just have my cake and eat it too.
Questions regarding cake:
It seems that cake3 is your invention, correct?
I will have to install Haskell to use it, correct?
(I have installed Haskell a few times in the past, but now I am on a new Debian machine with almost nothing - only Ur/Web. I imagine it is now time to install Haskell too.)
Idiom 4: This is interesting, suggesting that the most important thing to capture or know (ie parameterize) about any Layout is its width.
Questions:
https://github.com/grwlf/urweb-etab/blob/master/Gregorian.ur
(1)(a) Where does the mkOrd function come from?
Idiom 5:
As deceptively simple as this may appear, it is truly epic:
https://github.com/grwlf/urweb-prelude/blob/master/src/Prelude.ur
It's very yin-hang or Hegelian in that it defines both:
constructing the product and deconstructing the projection
in a single phrase,
In some informal categorical sense it is a like a "one-line left adjunct" - similar to some informal categorical ideas from David Ellerman (a professor at Boston University):
http://www.ellerman.org/Davids-Stuff/Maths/Conc-Univ.pdf
Elsewhere at the end of in Etab.ur I see a similar elegant pairing of constructor/deconstructor (but now using records with uniquely named fields):
This is very well-written and instructive.
Idiom 6: Type of error message defaults (of course!) to XML fragment
A naive programmer might ask "hmm, how do I return an error message, where do I return it, what type should it be, how do I get it up into that little box called a 'flash' on the next page?".
Now I see from your simple example that a wise programmer knows that any bit of UI (including an error message) is simply an XML fragment - to be spliced in later wherever needed.
Question:
In the function definitions:
https://github.com/grwlf/urweb-prelude/blob/master/src/Prelude.ur
What does this part mean?
Is this somehow saying that
a
is a type which is in typeclassEq
?Is there some intuitive or informal sense to using a wildcard
_
in this position?I again see a wildcard _ in this position at the end of
Prelude.ur
, in functionsshow_pair
andshow_option
:It seems to be saying to me that:
eq a
, or of typeshow a
._
is populated or not.But it at least does seem to be saying that the following applications:
do indeed return a valid type (regardless of whether populated or not), so this seems to be a declaration that type a is a member of typeclass
Eq
(resp.Show
).Idiom 7: ML data & SQL data
This is interesting to see the interaction between ML types and SQL records:
Conclusions and related Issues:
My experience is more in at algebraic data types and back-end (SQL) data modeling.
I am afraid of writing code involving events, timing, throttling / debouncing, interactivity - all the stuff involved in front-end development.
I imagine that these problems involve "co-algebraic process types" - the dual of my experience in algebraic data types.
It has has always been hard for me to understand the syntax and semantics of JavaScript (but easier to read things like CoffeeScript, Babel, ClojureScript, which use a more "functional" syntax.)
But now I think must force myself to learn enough front-end programming just to get the few data-bound UI widgets I need to put on the front-end of all databases:
I am still unsure if I should "wrap" an existing JavaScript library such as Mithril, as discussed here:
https://github.com/StefanScott/urweb-crudcrud/issues/4
You already provide libraries which wrap the more-standard, more-complete JavaScript library JQuery. So this means that one option would be for me to simply re-use your Ur/Web FFI code for JQuery. This would probably be easier in the beginning - after I to understand how to use your cake.
If I am using JQuery, then perhaps this means I could also use the sophisticated autocomplete widgets already developed which require JQuery:
I have been getting compiler errors doing this previously, described here:
https://github.com/StefanScott/urweb-crudcrud/issues/1 https://github.com/StefanScott/urweb-crudcrud/issues/2
But now I am thinking maybe I can use your Unsafe.s2xhead and Unsafe.s2xbody functions to solve this, by "splicing in" (inserting) the unsafe fragments which had been causing the compiler errors.
Question:
So, in some sense, the functions
Unsafe.s2xhead
andUnsafe.s2xbody
are "splicing in" (inserting) arbitrary HTML fragments and avoiding scrutiny by the Ur/Web compiler?Thank you for the code and examples you have provided!
PS - How are you surviving, doing this database work in Ur/Web, still with no UI autocomplete widget to let the user select a value for a foreign-key field??