Although I liked the idea presented by Jay Fields on infoq, I didn’t care for his use of regular expressions. However, I couldn’t think of anything better. Then I discovered the Treetop gem from Jan Kassens. This is an attempt to objectify some natural language. I don’t plan on making it a full language parser. But, as Jay Fields points out, a small set of natural language can be used to implement programming.
Currently it’s only a proof of concept.
DSL:
Begin Lunch/Break at 12:00.
One action is composed this way<super>i</super>:
Object: Lunch/Break, # The dsl knows how to use this as an identifier to find the appropriate domain object Method: Begin, Arguments: at 12:00.
DSL:
End Lunch/Break at 1:00 am, Start Something at 1:00 pm, and end something at 1:00 pm.
List of actions:<super>i</super>
[ { Object: Lunch/Break, Method: End, Arguments: at 1:00 am, }, { Object: Something, Method: end, Arguments: at 1:00 pm, }, { Object: something, Method: end, Arguments: at 1:00 pm, }, ]
DSL:
Create a project Something on 5/5.
Composition:
Class: Project Identifier(name): Something Method: Create Arguments: on 5/5
There can also be a difference, depending on the methods involved, between the (linguistic) article being used:
Create a project Name .... # Project.new :name => Task, ...args
vs.
Begin Name on ... # project = Project.find_by_name Name # project.begin args
or.
Finish the Name ... # project = Project.find_by_name Name # project.begin args
There are obvious assumtions here. These examples wouldn’t directly translate if the sentence read, “Finish project 1”, however, there is already a difference in how you have to refer to these entities. I suspect that this can be handled.
<super>i</super> Format is strictly used for clarity.
Classes are dependant on context. Context is provided by the app that includes them.
Article => Class e.g. The Project => class Project
include DataMapper::Resource #...
end
Adjective => Attribute e.g. Named Something => {object}.named == ‘Something’
Verb => Method e.g. begin {project} at {time} => {object}.begin( time )
Noun => Object/Instance e.g. Something => Project.first( :name => “Something” )
I can see this as being a general use case for coupling natural language to all sorts of things. E.g. commands, api’s other than ORM’s, etc. However, I’m currently working on getting the base capabilities worked out.
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Copyright © 2010 Scott Noel-Hemming. See LICENSE for details.