Re: ShEx DSL

Hi Gregg,

Thank you for starting a discussion on this!

The example reminds me of the pseudo-code syntax that Karen
improvised for the 2009 Guidelines for Dublin Core Application Profiles
[1], using terminology (DescriptionSet, Description, Statement
template...) from Mikael Nilsson's 2008 Description Set Profile
Constraint Language [2], e.g.:

    DescriptionSet: MyBookCase
       Description template: Book
       minimum = 1; maximum = 1
    Statement template: title
    minimum = 1; maximum = 1
      Property: http://purl.org/dc/terms/title
      Type of Value = "literal"
    Statement template: dateCreated
    minimum = 0; maximum = 1
      Property: http://purl.org/dc/terms/created
      Type of Value = "literal"
      Syntax Encoding Scheme URI = http://purl.org/dc/terms/W3CDTF

One advantage of the DSP is that it had the notion of a graph as a set
of Descriptions (a DescriptionSet), where each Description was a set of
statements about exactly one resource.  This idea derived from the
insight that a typical library catalog record did not just describe a
book, but included information descriptive of the author (e.g.,
"1818-1883") and publisher (e.g., "Berlin").  The DSP also had a notion
of mandatory Descriptions within a DescriptionSet (e.g., a mandatory
Book description, as in the example above, with optional descriptions of
Authors), and of the type of value (e.g., literal versus "non-literal"
URI or blank node).

If I'm correctly guessing your intentions, and omitting the reference of
the graph to match, I'm wondering if one might capture some of these
ideas.  I'd also like to put in a plug for snake case, which I find
marginally more readable.  So something like:

    ShEx:DSL do
      prefix dc:   "http://purl.org/dc/terms/"
      prefix rdf:  "http://www.w3.org/1999/02/22-rdf-syntax-ns#"

      description_set "MyBookCase" do
        description "Book" do
          expect_property "dc:title", exactly: 1.times
        end
      end, at_least: 1.times
    end

Tom

[1] http://dublincore.org/documents/profile-guidelines/
[2] http://dublincore.org/documents/dc-dsp/

> I was speaking with Tom and Karen about ways to make ShEx more approachable for non-programmers by allowing an alternative syntax to ShExC and JSON. Ruby is often used for creating Domain Specific Languages, which take advantage of Ruby syntax to make programming seem less like programming. This is done, not by writing a parser, but using Ruby Blocks and instance methods to describe behavior. Examples of popular DSLs in Ruby include ActiveRecord [1]. RDF.rb uses DSLs for writing queries [2] and ActiveTriples[3] which uses an ActiveRecord-like syntax for accessing objects in a graph.
> 
> As an example of what a ShEx-like DSL might look like, I took to do a pseudo-translaction of my DOAP schema [4]:
> 
>       PREFIX doap:  <http://usefulinc.com/ns/doap#>
>       PREFIX dc:    <http://purl.org/dc/terms/>
>       <TestShape> EXTRA a {
>         a doap:Project;
>         (doap:name;doap:description|dc:title;dc:description)+;
>         doap:category*;
>         doap:developer IRI;
>         doap:implements    [<http://shex.io/shex-semantics/>]
>       }
> 
> Which might look something like the following:
> 
>       ShEx:DSL do
>         prefix doap: "http://usefulinc.com/ns/doap#"
>         prefix dc:   "http://purl.org/dc/terms/"
>         prefix rdf:  "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
> 
>         withGraph "etc/doap.ttl"
>         matchNode "http://rubygems.org/gems/shex", using: "TestShape"
> 
>         describeShape "TestShape" do
>           allowProperty "rdf:type", atLeast: 0.times
>           expectProperty "rdf:type", toInclude: "doap:Project", exactly: 1.times
>           matchAll do
>             matchEither do
>               expectProperty "doap:name", exactly: 1.times
>               expectProperty "doap:description", exactly: 1.times
>             end
>             matchEither do
>               expectProperty "dc:title", exactly: 1.times
>               expectProperty "dc:description", exactly: 1.times
>             end
>           end
>         end, atLeast: 1.times
>         expectProperty "doap:catagory", atLeast: 0.times
>         expectProperty "doap:developer", toInclude: {node ofType: IRI}
>         expectProperty "doap:impelements", toInclude: "http://shex.io/shex-semantics/"
>       end
> 
> This makes use of ruby Ruby block-syntax (do…done) to describe behavior using instance methods within different class instances. The outer-most DSL describes prefix mappings, associates a graph to match (could be provided separately), and, in this case, a single node map to “TestShape”.
> 
> “TestShape” is describe as a shape with either TripleExpressions (expectProperty), or shape expressions. The outer-most is taken to be a matchAll (EachOf).
> 
> I’d be interested if there is interest in such an approach. Of course, this takes advantage of Ruby syntax, and to make something interoperable might require a parsable grammar. But, at least for Ruby, this might provide some advantages over raw ShExC/J.
> 
> Perhaps we can add an agenda item for Tuesday.
> 
> Gregg Kellogg
> gregg@greggkellogg.net
> 
> [1] http://guides.rubyonrails.org/active_record_basics.html
> [2] http://www.rubydoc.info/gems/rdf/RDF/Query
> [3] https://github.com/ActiveTriples/ActiveTriples
> [4] https://github.com/ruby-rdf/shex/blob/develop/etc/doap.shex

-- 
Tom Baker <tom@tombaker.org>

Received on Monday, 9 October 2017 13:03:15 UTC