Comments (6)
I thought I'd try to fix this trivial-looking bug but after a little thought I'm not sure why this is a bug. Since Xml
is a type alias for XmlItem
, one can also write []
instead of <#/>
, i.e.
links> [] == <#/>;
true : Bool
Moreover, why is the proposed solution to display it as the empty string ""
(which does not parse to an empty Xml
value) instead of "<#/>"
(which does)?
The only inconsistency I see about the current situation is that there is no way to write a single XmlItem
in Links syntax, because writing something like <a>foo</a>
yields a single-element list (rendered the same way), while <#><a>foo</a></#>
also yields a single-element list that is rendered as <a>foo</a>
.
links> var x = <a>foo</a>;
x = <a>foo</a> : Xml
links> var y = <#><a>foo</a></#>;
y = <a>foo</a> : Xml
I think it would be better for <a>foo</a>
on its own to have type XmlItem, and then we could view <#><a>foo</a><b>bar</b>...</#>
exactly as syntactic sugar for [<a>foo</a>,<b>bar</b>,...]
, just as one would expect from the aliasing of Xml
as [XmlItem]
.
It might also make more sense to use the Xml
type for individual trees rather than hedges (sequences of trees) since an XML document is a single tree, not a sequence of trees.
from links.
The program page <#/>
generates a web page with content []
. It would make more sense to generate an empty string, that being the denotation of </#>
as serialised XML.
from links.
We had a discussion about 10 years ago about whether XML literals should have type XmlItem
or type [XmlItem]
. Unfortunately, I don't remember the justification for the current design, but if you want to change the design then I suggest you think carefully about the consequences. At that point we were considering using an XDuce-style regular expression type system, which we rapidly abandoned. Given that XML is still isomorphic to a plain old algebraic data type, one option would be to define it simply as a type alias - though that could conceivably become inconvenient if we were to try to capture more aspects of XML.
from links.
There seem to be two or more separate issues here:
- what value does
<#/>
have? In the current design, its value is[]
; it is equal to the empty list, which is a value. - how should we print the value of
<#/>
at the REPL? In the current design, it is printed out the same as the empty list, but sequences of XML wrapped in<#>...</#>
are printed as XML strings without either enclosing[]
brackets or enclosing<#>...</#>
tags, since the latter are not legal XML. Other XML values are printed as XML strings that Links will not re-parse to the same value. - how should we print it when rendering it as a page)? currently this is done the same as for REPL output, which is what we want for nonempty values but not for
<#/>
.
I think it is desirable for the default string representation of a value to be a string that parses back to that value, when this makes sense.
So one fix that does not require changing the existing type structure could be to use the existing Value.string_of_value to print out the value of <#/>
, as []
as usual, and use a different function render_xml
to "render" an XML value as a well-formed xml string when sending a HTTP response. Decoupling these two ways to render XML would also allow printing XML values as lists of XMLItems more uniformly. I'll give that a try before proposing something more radical.
from links.
Hmm. So the basic problem is that in webif, we call "string_of_value", which does not call "string_of_xml" directly. Instead, it prints the empty list as []
, prints nonempty lists of XML values by just concatenating the results using string_of_item
, and prints isolated XML(item) values using string_of_item
Likewise we call string_of_value
in the REPL and get the same behavior.
When we have an empty list, we have no way of knowing that it is an empty list of XMLitems because we don't have type information.
So would one solution be to change the calls to Value.string_of_value
in webif.ml (for the cases returning text/html) to instead be Value.string_of_xml
? This wouldn't work exactly because the values are Links values = Links lists of XML(xmlitem)s, not OCaml lists of xmlitems. But something like this should work, because we know the value should be a list of xmlitems, so we can do the right thing even if it is empty.
In any case, I think in a good design page <#/>
would not even be well-formed, since the content of a page should be a single XMLitem, not a list of them (possibly none or several).
from links.
Revisiting this, it seems that the following toy program no longer exhibits the undesired behavior:
fun main(_) { page <#/> }
fun setup() {
var _ = addRoute("",main);
servePages()
}
setup()
When run, this yields HTML that renders as an empty page, and on viewing the source it appears that []
is no longer being printed when we emit the page. I'm not sure of the reason for this, but I believe the original problem this issue flags is no longer present.
It is still the case that in the REPL the value of the expression <#/>
is printed as []
. I don't see an easy way to fix this short of adding some kind of run-time tag to Nil
to indicate when it was an empty Xml
that should be printed as <#/>
; if we had something like type classes and defined Xml
as a new type rather than as a synonym for [XmlItem]
then we could customize the printing behavior to print <#/>
but this would entail lots of other changes. In any case, the issue seems to have been about the serialization of empty pages which now seems to be behaving as intended anyway.
So I think this can be closed.
from links.
Related Issues (20)
- Error when calling non-closed local server functions HOT 7
- Unbound effect variables in type aliases when effect sugar is enabled
- Incorrect resolution of shadowed names in mutual blocks HOT 2
- "flat" and "nested" kinds for query results
- Lens refactor HOT 2
- Kind inference
- dateToInt -> intToDate does not roundtrip depending on time zone HOT 3
- Interaction between session-typed communication and effects is broken even without multi-shot continuations
- Incomplete rows can trigger an internal error
- Some questions about your work :) HOT 3
- REPL prompt disappears HOT 5
- "opam install links" doesn't produce linx executable in Ocaml 5.0.0 HOT 8
- Restriction of using row polymorphism for the effect system
- Recent versions of ppx_sexp_conv cause warnings in lens code
- Untypesettable session types
- Implement delegatable channels
- Rename links-mysql8 driver to links-mysql? HOT 2
- SPARQL improvements
- ppx_sexp_conv creates code triggering warning 40 HOT 3
- Incompatible with OCaml 4.08 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from links.